这段代码在 GCC 8.3.1 上编译并运行良好:
#include <stdio.h>
#define BUF_SZ 3
int main(void)
{
int foo = 99;
int *p = (int *)&foo;
char buffer[BUF_SZ];
snprintf(buffer, BUF_SZ, "%02d", *p);
fprintf(stdout, "%s\n", buffer);
return 0;
}
me@localhost:/tmp$ gcc -v 2>&1 | grep "gcc version"
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)
me@localhost:/tmp$ gcc -Wall test.c && ./a.out
99
也许这个版本的 GCC 没有问题,但我确实在上面注意到你有
snprintf(buffer, "%02d", *p);
- 因为你缺少 snprintf 的 size 参数,所以根本不应该编译。
此外,值得注意的是,对于以下差异,GCC 8.3.1 确实会按预期抛出错误:
me@localhost:/tmp$ diff test.c test_format-truncation-warning.c
11c11
< snprintf(buffer, BUF_SZ, "%02d", *p);
---
> snprintf(buffer, BUF_SZ, "%03d", *p);
对于偶然发现此页面的其他人,他们正在为 -Wformat-truncation 警告寻找更通用的“解决方法”。这是一个使用 memcpy() 的方法,尽管我怀疑 -Wformat-truncation 的作者打算将其用作 strncpy() 的替代方法。
#if USE_STRNCPY
/* Note that using size of 'NAME_MAX' is just to prevent recent versions
* of GCC from throwing '-Wformat-truncation' errors. Otherwise, a char
* buffer of len UUID_STR_LEN would be fine.
*/
char tmp_fname[NAME_MAX + 1] = {0};
strncpy(tmp_fname, input_file_name, NAME_MAX);
#else
char tmp_fname[UUID_STR_LEN] = {0};
memcpy((void *)tmp_fname, (void *)input_file_name,
MIN(UUID_STR_LEN - 1, strnlen(input_file_name, UUID_STR_LEN - 1));
#endif