警告 "format not a string literal and no format arguments" 未出现在最新的 gcc 版本中
Warning "format not a string literal and no format arguments" not appearing on latest gcc version
在我的代码中,我使用以下行打印一个 char readbuffer[1];
数组(大小为 1 的字符数组):
printf(readbuffer);
这在我的电脑上编译和工作没有问题(Arch Linux,gcc 版本 7.3.1+20180406-1
)。但是,当我将包含此代码的作业提交给我的讲师时,实际上他在编译我的代码时收到了编译器警告:
shell.c:89:20: warning: format not a string literal and no format arguments [-Wformat-security]
printf(readbuffer);
他使用的是 16.04 LTS 版本的 gcc/clang 版本。我们都使用相同的编译器标志。
这是为什么?在新的 gcc
版本中,这突然不再是问题了吗?如果是,为什么不呢?
请注意:我不想知道如何解决这个问题,只是想知道为什么警告在 gcc 版本之间不一致。
这不是GCC版本不同造成的。相反,Ubuntu has modified GCC to enable -Wformat -Wformat-security
by default。如果你在 Arch Linux 上传递这些选项,你应该会在那里看到相同的行为。
I don't want to know how to solve this issue ...
是的,你真的做到了!
除非你的char[1]
变量总是包含[=14=]
,否则你所做的是不安全的。和。如果确实包含那个,那么你所做的就没什么了:-)
做你想做的事情的正确方法是,假设需要 printf
:
printf("%.1s", readbuffer);
这将确保您不会试图阅读过去的单个字符。当然,如果你知道总会有一个角色,就用:
putchar(*readbuffer);
至于为什么不同的 gcc
版本报告不同,这可以归结为随时间的简单改进。这就是为什么,例如,gcc
会抱怨格式说明符数量与参数数量之间不匹配的原因,例如:
printf ("%s %d\n", "hello");
而其他一些实现可能不会。
具体来说,虽然标准规定 必须 报告为诊断,但它不限制 可以 报告的实施除此之外的诊断。
更高版本的编译器可能会添加或删除这些可选诊断,或者更改它们决定报告它们的方式。
在我的代码中,我使用以下行打印一个 char readbuffer[1];
数组(大小为 1 的字符数组):
printf(readbuffer);
这在我的电脑上编译和工作没有问题(Arch Linux,gcc 版本 7.3.1+20180406-1
)。但是,当我将包含此代码的作业提交给我的讲师时,实际上他在编译我的代码时收到了编译器警告:
shell.c:89:20: warning: format not a string literal and no format arguments [-Wformat-security]
printf(readbuffer);
他使用的是 16.04 LTS 版本的 gcc/clang 版本。我们都使用相同的编译器标志。
这是为什么?在新的 gcc
版本中,这突然不再是问题了吗?如果是,为什么不呢?
请注意:我不想知道如何解决这个问题,只是想知道为什么警告在 gcc 版本之间不一致。
这不是GCC版本不同造成的。相反,Ubuntu has modified GCC to enable -Wformat -Wformat-security
by default。如果你在 Arch Linux 上传递这些选项,你应该会在那里看到相同的行为。
I don't want to know how to solve this issue ...
是的,你真的做到了!
除非你的char[1]
变量总是包含[=14=]
,否则你所做的是不安全的。和。如果确实包含那个,那么你所做的就没什么了:-)
做你想做的事情的正确方法是,假设需要 printf
:
printf("%.1s", readbuffer);
这将确保您不会试图阅读过去的单个字符。当然,如果你知道总会有一个角色,就用:
putchar(*readbuffer);
至于为什么不同的 gcc
版本报告不同,这可以归结为随时间的简单改进。这就是为什么,例如,gcc
会抱怨格式说明符数量与参数数量之间不匹配的原因,例如:
printf ("%s %d\n", "hello");
而其他一些实现可能不会。
具体来说,虽然标准规定 必须 报告为诊断,但它不限制 可以 报告的实施除此之外的诊断。
更高版本的编译器可能会添加或删除这些可选诊断,或者更改它们决定报告它们的方式。