-Wformat-truncation错误,将2-3个字节写入2-6个字节的区域。

问题描述 投票:0回答:1

我有一个问题,就是下面的fuction。

std::string TimeToTimestampStr(time_t t)
{
    tm aTm;
    ACE_OS::localtime_r(&t, &aTm);
    //       YYYY   year
    //       MM     month (2 digits 01-12)
    //       DD     day (2 digits 01-31)
    //       HH     hour (2 digits 00-23)
    //       MM     minutes (2 digits 00-59)
    //       SS     seconds (2 digits 00-59)
    char buf[20];
    snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d",
             (aTm.tm_year+1900)%10000,
             (aTm.tm_mon+1)%13,
             aTm.tm_mday%32,
             aTm.tm_hour%24,
             aTm.tm_min%60, // warning on this parameter
             aTm.tm_sec%60);
    return std::string(buf);
}
error: ‘%02d’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 2 and 6 [-Werror=format-truncation=]

不知道为什么会有这样的问题, 2 -3个字节不应该被截断在一个2 -6个字节大小的区域里, 那么这个警告的原因是什么? 最好的猜测是,3个字节可能被区域的下限(2)截断?但这完全是假的--region的大小是6个字节以内,只有在写入超过6个字节时才应该截断......对吧?

EDIT: 我发现的其他问题都与向一个较少字节的区域写入更多字节有关,这导致我不得不添加%来强制执行输入的大小上限。

c++ gcc directive format-truncation
1个回答
1
投票

tm 领域是 int 所以有 签署对编译器来说,你计算的所有数字都可以是负数,但你的数组的大小是假定所有的数字都是正数,因为你知道 localtime_r 但对于编译器来说,26个字节是必要的,因为最坏的情况就像 -9999--13--31_-23--59--59

当然,有了20号,就没有未定义的行为,因为你使用了 snprintf 而非 printf,但例如用 -Wall 启用警告的生产

用至少26号代替20号,你就不会有警告。

© www.soinside.com 2019 - 2024. All rights reserved.