【问题标题】:warnings when activating the optimization options激活优化选项时的警告
【发布时间】:2012-06-16 08:37:46
【问题描述】:

我在一个 c 程序中使用 scanf 从 STDIN 读取一个 int:

scanf("%d", &n);

当我编译启用优化的 c 程序时,我收到一些警告:

gcc main.c -lm -lpthread -O2 -o main
main.c: In function ‘main’:
main.c:45: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
main.c:50: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result

但是当我删除优化选项时,为什么我没有收到这些警告?

gcc main.c -lm -lpthread -o main

P.S:我没有使用 -Wall 或类似的东西。

【问题讨论】:

  • 发布更多代码将帮助我们分析您的问题。

标签: c linux gcc scanf


【解决方案1】:

更改优化器设置会改变编译器分析代码的程度(以及方式)。

未启用优化(或设置不够高)时,部分程序流程分析未完成,因此不会发出相关警告。
您会经常看到“未使用的变量”警告 - 这些需要对代码进行分析,超出了简单编译所需的范围,因此您通常只会在启用优化的情况下获得它们。

(你真的应该用-Wall编译。)

【讨论】:

  • 您可以查看-Wuninitialized 文档(在手册页中),例如:“因为这些警告取决于优化,所以存在警告的确切变量或元素将取决于精确的优化选项和使用的 GCC 版本。”
【解决方案2】:

-Wunused-resultenabled by default:因为你需要用__attribute__ ((warn_unused_result)) 装饰一个函数来触发警告,所以误报只会在使用过度时发生。

即使没有传递额外的标志,gcc 应该产生警告。但是,正如 Mat 解释的那样,编译器不会在不提高优化级别的情况下进行必要的控制流分析。

通过添加-Wno-unused-result 修复您的代码或使警告静音。 将返回值转换为void 也可能会这样做。

要使代码中的警告静音,您需要将返回值分配给一个虚拟变量,然后您可以将其强制转换为 void 以避免出现关于未使用变量的新警告。也可以用 C99 复合文字代替显式声明的变量(使用 gcc 4.5.3 测试)。

这确实不是最佳选择 - 我真的期待我最初提议的 void-cast 工作......

【讨论】:

  • @obounaim:我不知道是不是,但快速在线搜索显示与此相关的错误(例如gcc.gnu.org/bugzilla/show_bug.cgi?id=43361)标记为 WONTFIX
  • 实际上有很多误报,scanf 就是其中之一。这些在 glibc bugzilla 上定期报告,其中一些得到了修复。例如,可以完全安全地使用scanf-family 函数而无需检查返回值,只要您有另一种方法来确定它是否读取所有值,或者您是否使用默认值预先填充要读取的变量可以在没有合适的输入时使用。
  • @R..:我的立场是正确的;此外,void 的演员表并没有消除我的 gcc 4.5.3 上的警告,这是出乎意料的......
  • @R.. 这可能适用于sscanf,但scanf 从标准输入读取,没有人应该对从中读取的内容做出任何假设。不检查来自scanf 的结果是一种罪过。总是。
  • @R.. (void) 不要停止我的 gcc 4.4.3 上的警告
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 2018-12-17
  • 2017-12-08
相关资源
最近更新 更多