【问题标题】:Why #pragma optimize("", off)为什么#pragma optimize("", off)
【发布时间】:2015-05-16 00:09:02
【问题描述】:

我正在审查一个 C++ MFC 项目。在一些文件的开头有这样一行:

#pragma optimize("", off)

我知道这会关闭所有以下功能的优化。但这样做的动机通常是什么?

【问题讨论】:

  • 也许程序员喜欢程序爆炸时可靠的堆栈跟踪。也许他试图解决代码优化器错误。也许他不知道自己在做什么,并且施加了货物崇拜。
  • 另一个原因是混淆生成的二进制文件。让逆向工程更难(当然如果源代码是开放的,这是没有意义的)。
  • @freakish 似乎 Themida 在试图混淆 VM 中的 return 语句时对此进行了转发,请参阅文档中的 screenshot

标签: c++ visual-studio mfc


【解决方案1】:

我专门使用它来在一组特定代码中获得更好的调试信息,而应用程序的其余部分是在优化的情况下编译的。当由于应用程序的性能要求而无法使用完整的调试版本运行时,这非常有用。

【讨论】:

  • 是的。这是开发大型项目时的常见做法。
【解决方案2】:

我见过正确的生产代码,但过于复杂,以至于让优化器产生了不正确的输出。这可能是关闭优化的原因。

但是,我认为代码更有可能只是错误,具有未定义的行为。优化器会暴露这一点并导致不正确的运行时行为或崩溃。如果没有优化,代码恰好“工作”。而不是找到并消除潜在问题,而是通过禁用优化并将其留在那里来“修复”它。

当然,这几乎是脆弱和变通办法所能得到的。新硬件、新操作系统补丁、新编译器补丁,任何这些都可能破坏这样的“修复”。

即使编译指示是出于第一个原因,它也应该被大量记录。

【讨论】:

  • 谢谢。没有围绕这些行的文档。我想我会尝试移除它们并留意副作用。
【解决方案3】:

这些在代码库中的另一个替代原因......这是一个意外。

这是一个非常方便的工具,可以在调试时关闭特定文件的优化器 - 正如 Ray 上面提到的那样。

如果在提交之前没有仔细检查更改列表,那么这些行很容易进入代码库,因为在提交其他更改时它们“意外地”仍然存在。

【讨论】:

  • 对于像 UE4 和 webkit 这样的大型代码库,这是一个方便的技巧。
【解决方案4】:

我知道这是一个老话题,但我想补充一点,使用此指令还有另一个原因 - 尽管与大多数应用程序开发人员无关。

在编写设备驱动程序或其他低级代码时,优化器有时会产生无法与硬件正确交互的输出。

例如,需要读取内存映射寄存器(但不使用读取的值)来清除中断的代码可能会被编译器优化,从而生成不起作用的汇编代码。

这也可能说明为什么(如 Angew 所指出的)该指令的使用应该被清楚地记录在案。

【讨论】:

  • 一个类似的情况是当您想要为加密目的执行一组精确的操作时。侧信道攻击可以测量各种分支执行所花费的时间/功耗,两个看起来相似的代码路径上的优化可能不相同,从而泄露信息en.wikipedia.org/wiki/Timing_attack
  • 或者防止繁忙的等待循环被优化掉(你希望保留时间的副作用)。尝试清除内存块时,还请查看此页面以了解一般问题:wiki.sei.cmu.edu/confluence/display/c/…
【解决方案5】:

它允许您在发布模式下进行调试。

【讨论】:

猜你喜欢
  • 2010-10-21
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多