【问题标题】:Warning "format not a string literal and no format arguments" not appearing on latest gcc version警告“格式不是字符串文字且没有格式参数”未出现在最新的 gcc 版本上
【发布时间】:2018-05-01 05:59:02
【问题描述】:

在我的代码中,我使用以下行来打印 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 版本不一致。

【问题讨论】:

  • 如果您只想打印单个字符,请使用putchar。无需设置缓冲区并 NUL 终止它(您没有这样做,导致未定义的行为)。

标签: c gcc compiler-warnings gcc-warning linux-distro


【解决方案1】:

我不想知道如何解决这个问题...

是的,你真的做到了!

除非您的char[1] 变量总是 包含\0,否则您所做的是不安全的。和。如果它确实包含它,那么你所做的就没什么:-)

假设需要printf

printf("%.1s", readbuffer);

这将确保您不会尝试读取该单个字符。当然,如果你知道总会有一个字符,那就用:

putchar(*readbuffer);

关于为什么不同的gcc 版本报告不同,这可以归结为随着时间的推移而进行的简单改进。例如,gcc 会抱怨格式说明符数量与参数数量不匹配的原因与此相同:

printf ("%s %d\n", "hello");

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

具体来说,虽然标准规定了必须报告为诊断的内容,但它并没有限制可能报告为诊断的实现。

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

【讨论】:

  • 我之所以包含I don't want to know how to solve this issue ... 这一行是因为已经有很多 StackOverflow 页面对此进行了解释。问题的原因是找出为什么 gcc 选择在这个较新的/arch gcc 版本中省略特定的编译器警告。
【解决方案2】:

这不是由 GCC 版本的差异引起的。而是Ubuntu has modified GCC to enable -Wformat -Wformat-security by default。如果您在 Arch Linux 上传递这些选项,您应该会在那里看到相同的行为。

【讨论】:

  • 这对我来说确实有意义。我已经想到会是这样,因为从来没有任何真正的安全问题。
  • 由于这里唯一有效的格式参数是空字符串,并且允许编译器假设未定义行为不会发生,我想它有权消除对 printf 的调用.但是,如果它费心去做那个测试,我会感到惊讶——这不是一个很可能的优化——如果它不做测试,它也不会抑制警告。
  • 绝对存在安全问题,因为您不知道内存中该数组后面的内容,并且 printf 将继续读取,直到找到 NUL。 (另外,考虑单个字符是% 的可能性。)
  • @rici 换句话说,如果格式字符串不以空字符结尾,则会出现安全问题。这是真的,但不是该警告旨在警告的内容。当它在编译时被检测到时,会有一个单独的警告(“警告:未终止的格式字符串”)。而且我同意对数组长度 1 的特殊情况检查没有意义,但是检查所有长度的数组以查看它们是否可能包含 % 字符的一般检查可能有意义。但诚然,这仍然比我在免责声明中提出的可能性要小。
  • @rici 不管怎样,我现在已经能够确认这毕竟不是由 GCC 版本的差异引起的。
猜你喜欢
  • 2013-04-07
  • 2010-12-13
  • 2011-05-24
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
相关资源
最近更新 更多