警告 "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");

而其他一些实现可能不会。

具体来说,虽然标准规定 必须 报告为诊断,但它不限制 可以 报告的实施除此之外的诊断。

更高版本的编译器可能会添加或删除这些可选诊断,或者更改它们决定报告它们的方式。