【问题标题】:Warnings vs optimization gcc [closed]警告与优化 gcc [关闭]
【发布时间】:2021-12-30 22:30:25
【问题描述】:

我想知道当启用优化(O2 或 O3)时,编译器报告的警告(例如未使用的变量或控制到达非 void 函数的末尾)是否会影响程序(即崩溃)

你能给我一些例子吗?

【问题讨论】:

  • 好吧,“控制到达非空函数的末尾”会导致未定义的行为,您可能需要在考虑优化之前修复它。
  • 您正在寻找一个编译器诊断示例,它在优化关闭时不伴随程序故障,但在优化打开时伴随程序故障?
  • 未使用的变量,没有。不从需要它的函数返回值,是的,它与优化无关,它总是错误的。
  • @dratenik 这是一个很好的例子。编译器似乎认为foo 没有return 语句,因此它永远无法返回。因此,mainfoo 调用后无法到达printf,也无法返回。因此不需要mainret 指令。然后碰巧链接器会将_start直接放在二进制文件中的main之后,因此程序不断流回到_startmain

标签: c++ linux gcc


【解决方案1】:

警告表明您的代码中可能存在错误。但是,有没有警告,有没有开启优化,并不影响代码是否正确。

unused variable 之类的警告只是表明您可能打算在某处使用该变量但忘记了。否则不会有变量存在的理由。

control reaches end of a non-void function 等警告更为严重。例如,在这种特定情况下,调用具有非 void 返回类型的函数会导致 未定义的行为,如果它的执行到达函数体的关闭 } 而没有通过之前的 return 语句返回。

在这种情况下,警告会通知您编译器检测到该函数可以使用该路径来获取此结果的某些输入。这很可能是无意的,因为如果您使用该路径调用该函数,那么您的程序将具有未定义的行为。


当程序有未定义的行为时,你无法确定它会做什么,因为你的编译器/平台没有额外的保证。它可能在优化时以一种方式运行,而在没有优化时以不同方式运行。对于不同的编译器版本,或者只是在不同的编译运行甚至程序执行之间,它也可能具有不同的行为。

然而,在这种情况下,更高的优化级别更有可能产生意外的行为,因为编译器会更加努力地将代码转换为性能更高的形式,并且这样做会假设代码构造不会产生未定义的行为扩大可能的转换范围。

【讨论】:

  • 我见过带有未使用变量的代码,当这些未使用的变量被删除时,它们的行为会发生变化,即删除这些变量会暴露其他程序错误。例如,如果某些代码在数组末尾运行时会发生这种情况 - 并且添加一个变量(否则未使用)会改变症状(例如,改变整个程序的内存布局,或“未使用”变量被超出数组末尾的其他代码所取代)。这种情况可能非常令人不安,例如如果未使用的变量被不同函数中的代码篡改。
猜你喜欢
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多