如何在 gcc 中禁用编译器优化?

Posted

技术标签:

【中文标题】如何在 gcc 中禁用编译器优化?【英文标题】:How to disable compiler optimizations in gcc? 【发布时间】:2011-08-11 13:48:13 【问题描述】:

我正在努力学习汇编语言。我已经搜索并找到了如何反汇编 .c 文件,但我认为它会生成一些优化版本的程序。有什么办法可以让我看到与我的 C 文件相对应的确切汇编代码。

【问题讨论】:

控制优化的 gcc 选项gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Optimize-Options.html 优化后的代码与你的C文件对应的确切代码。查看未优化代码的反汇编会产生错误的印象。它会让你觉得你可以做得更好。 就像 Hans 说的 - 用汇编代码编写的想法是比编译器做得更好。如果您查看优化后的代码,您会发现这有多难! 相关:How to remove "noise" from GCC/clang assembly output? 为什么人们总是在没有正确阅读 Q 的情况下跳入 smarty cmets。很明显,用户希望输出尽可能清晰以帮助他。编译器比大多数编码器聪明得多,任何认为优化的代码对新手有帮助的人就像未优化的代码没有考虑过一样。他正在做的是一种非常常见的学习汇编程序并告诉 gcc 不要优化的方法。 【参考方案1】:

使用命令行选项-O0 (-[capital o][zero]) 禁用优化,使用-S 获取汇编文件。查看here 以查看更多 gcc 命令行选项。

【讨论】:

【参考方案2】:

您还可以使用 #pragma GCC push_options 在内部控制优化

#pragma GCC push_options
/* #pragma GCC optimize ("unroll-loops") */     

.... code here .....

#pragma GCC pop_options

【讨论】:

【参考方案3】:

很久以前,但仍然需要。

info - https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
list - gcc -Q --help=optimizers test.c | grep enabled
disable as many as you like with:
  gcc **-fno-web** -Q --help=optimizers test.c | grep enabled

【讨论】:

【参考方案4】:

gcc 选项-O 启用不同级别的优化。使用-O0 禁用它们并使用-S 输出程序集。 -O3 是***别的优化。

从 gcc 4.8 开始,优化级别 -Og 可用。它启用不干扰调试的优化,是标准编辑-编译-调试周期的推荐默认值。

要将程序集的方言更改为 intel 或 att,请使用 -masm=intel-masm=att

您还可以使用-fname 手动启用某些优化。

查看gcc manual 了解更多信息。

【讨论】:

如果您没有指定任何 -O 标志,-O0 是默认值(无优化)。 使用 -O0 仍然有优化:减少编译时间并使调试产生预期的结果。 @klm123 是的,但它是你可以得到的接近,总比没有好。 如果你有一个相当现代的支持 -Og 的 gcc,试试吧,我发现它通常提供比 -O0 更具可读性的汇编输出。 @ViktorDahl 感谢您的提示。我修改了答案。【参考方案5】:

要在没有复制省略的情况下进行测试并查看复制/移动构造函数/操作符的实际效果,请添加“-fno-elide-constructors”。

即使没有优化 (-O0 ),GCC 和 Clang 仍然会进行复制省略,这在某些情况下会产生跳过复制/移动构造函数的效果。有关复制省略的详细信息,请参阅this question。

但是,在 Clang 3.4 中,它确实触发了一个错误(没有调用构造函数的无效临时对象),该错误已在 3.5 中修复。

【讨论】:

【参考方案6】:

对于 gcc,你想省略传递给编译器的任何 -O1 -O2-O3 选项,或者如果你已经有了它们,你可以附加 - O0 选项再次将其关闭。它还可以帮助您添加 -g 进行调试,以便您可以在调试器中看到 c 源代码和反汇编的机器代码。

另请参阅:http://sourceware.org/gdb/onlinedocs/gdb/Optimized-Code.html

【讨论】:

【参考方案7】:

如果使用 gcc 命令行传递 -O0,则可以禁用优化。

例如将 .C 文件转换为 .S 文件调用:

gcc -O0 -S test.c

【讨论】:

-O0 是多余的,因为它是默认设置。

以上是关于如何在 gcc 中禁用编译器优化?的主要内容,如果未能解决你的问题,请参考以下文章

如何关闭 gcc 编译器优化以启用缓冲区溢出

禁用 GCC 中的所有优化选项

展开 gcc 编译器优化

(Linux)gcc进行优化编译的参数是啥?

如何禁用Ceph的编译器优化?

基于GCC的编译器的优化等级的执行原理