在我的代码中,我使用以下行来打印char readbuffer[1];
数组(大小为1的char数组):
printf(readbuffer);
这在我的电脑上编译和工作没有问题(Arch Linux,gcc version 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版本不一致。
答案 0 :(得分:1)
这不是由GCC版本的差异引起的。相反,Ubuntu has modified GCC to enable -Wformat -Wformat-security
by default。如果你在Arch Linux上传递这些选项,你应该会看到相同的行为。
答案 1 :(得分:1)
我不想知道如何解决这个问题...
是的,你真的做了!
除非您的char[1]
变量始终包含\0
,否则您所做的是不安全的。和。如果 包含它,你所做的就是什么: - )
正确的方法来做你正在尝试做的事情,假设需要printf
:
printf("%.1s", readbuffer);
这将确保您不会尝试阅读该单个字符。当然,如果你知道总会有一个角色,只需使用:
putchar(*readbuffer);
就不同gcc
版本的不同报告原因而言,这可以归结为随着时间的推移而进行的简单改进。例如,gcc
会抱怨格式说明符数量与参数数量不匹配的原因相同:
printf ("%s %d\n", "hello");
而其他一些实现可能不会。
具体而言,虽然标准要求将必须报告为诊断,但它不会限制可能报告的实施作为诊断之外的其他内容。
编译器的更高版本可能会添加或删除这些可选诊断,或更改他们决定报告的方式。