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

标签 c++ gcc directive format-truncation

我对以下功能有疑问:

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) 截断?但这完全是假的 - 区域的大小最多为 6 个字节,并且只有在写入超过 6 个字节时才应该截断......对吗?

编辑:我发现的其他问题与将更多字节写入较少字节的区域有关,这导致添加 % 以强制输入的大小上限。

最佳答案

tm中,字段是int,因此有有符号,对于编译器来说,您计算的所有数字都可以为负数,但您调整了大小你的数组假设都是正数,因为你知道 localtime_r 的作用,但对于编译器来说,26 个字节是必要的,因为最坏的情况就像 -9999--13--31_-23-- 59--59

当然,大小为 20 时不会有未定义的行为,因为您使用 snprintf 而不是 printf,但例如使用 -Wall 进行编译激活警告的产生

将尺寸 20 替换为至少 26,这样就不会出现警告

关于c++ - -Wformat-truncation错误将2-3个字节写入2-6个字节的区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61711224/

相关文章:

angularjs - 每次打开模态ui模态时,如何设置对textarea的关注?

javascript - 使用 Angular 从服务器端生成的下拉列表中获取选择属性值

c++ - 如何强制 Bazel 将库路径设置为所需的路径?

c++ - GCC 错误还是 UB?这段代码应该编译吗?

c++ - 定点组合器和显式结果类型

C++,从具有引用返回类型的函数返回什么以指示错误

c - 从 C 程序调用 GCC 时抑制错误输出

javascript - AngularJS 指令 : template with scope value (ng-bind-html)

c++ - 字符串类中 size() 和 at() 的不正确行为

c++ - 重载有理数类的 istream >> 运算符。不知道如何处理整数