有没有办法让 GCC 不优化任何函数调用?
在生成的汇编代码中,printf 函数被替换为 putchar。即使使用默认的 -O0
最小优化标志也会发生这种情况。
#include <stdio.h>
int main(void) {
printf("a");
return 0;
}
最佳答案
使用-fno-builtin禁用标准 C 函数的所有替换和内联。 (这对于假定 memcpy(x,y, 4)
将编译为未对齐/别名安全加载而不是函数调用的代码的性能非常不利。并禁用常量传播,例如strlen
的字符串文字。所以通常你会希望在实际使用中避免这种情况。)
或者使用 -fno-builtin-FUNCNAME
作为特定函数,例如 -fno-builtin-printf
。
默认情况下,一些常用的标准 C 函数被处理为内置函数,类似于 __builtin_popcount
。 printf 的处理程序将其替换为 putchar 或 puts
如果可能的话。
6.59 Other Built-in Functions Provided by GCC
默认情况下,printf("a")
等 C 语句的实现细节不被视为可见的副作用,因此不会保留它们。您仍然可以在调用站点设置断点并进入函数(至少在汇编中,或者如果安装了调试符号,则在源代码模式下)。
要禁用单个函数的其他类型的优化,请参阅 __attribute__((optimize(0)))
on a function或 #pragma GCC optimize
。但要注意:
The
optimize
attribute should be used for debugging purposes only. It is not suitable in production code.
您不能禁用所有 优化。一些优化是 GCC 在组装过程中通过内部表示进行转换的固有方式。参见 Disable all optimization options in GCC .
例如,即使在 -O0
时,GCC 也会将 x/10
优化为乘法逆。
它仍然将 C 语句之间的所有内容存储到内存中(为了一致的调试;that's what -O0
really means); GCC 没有尝试尽可能天真地将 C 音译为汇编语言的“完全愚蠢”模式。为此使用 tcc
。 Clang和 ICC -O0
比 GCC 更直白一些,MSVC 也是如此。 Debug模式。
请注意,-g
永远不会对代码生成产生任何影响,只会对发出的元数据产生影响。 GCC 使用其他选项(主要是 -O
、-f*
和 -m*
)来控制代码生成,因此您始终可以安全地启用-g
不会影响性能,除了更大的二进制文件。它不是调试模式(即-O0
);它只是调试符号。
关于c - 我怎样才能让 GCC 编译器不优化像 'printf' 这样的标准库函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57062430/