Yur*_*que 5 c x86 assembly gcc compiler-optimization
出于好奇,我想知道gcc是否可以通过某种方式不优化任何函数调用?
在生成的汇编代码中,printf函数由putchar代替。即使使用默认的-O0最小优化标志,也会发生这种情况。
#include <stdio.h>
int main(void) {
printf("a");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(Godbolt显示GCC9正在执行此操作,clang8使其保持不变。)
使用-fno-builtin禁用所有替换和等同的标准C函数的内联。
或-fno-builtin-FUNCNAME用于特定功能,例如-fno-builtin-printf。
默认情况下,某些常用的标准C函数被视为内置函数,类似于__builtin_popcount。printf的处理程序将其替换为putchar或puts(如果可能)。 https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
printf("a")默认情况下,不会将C语句的实现细节视为可见的副作用,因此也不会保留这些东西。您仍然可以在调用站点上设置断点并进入函数(至少在asm或如果安装了调试符号的情况下,在源代码模式下)。
要为单个功能禁用其他类型的优化,请参见__attribute__((optimize(0)))功能或#pragma GCC optimize。但要注意:
该
optimize属性应仅用于调试目的。它不适用于生产代码。
您不能禁用所有优化。gcc通过内部表示形式转换为asm的方式中固有的一些优化。请参阅禁用GCC中的所有优化选项。
例如,即使在-O0gcc也会将其优化x / 10为乘法逆。
它仍然将所有内容存储在C语句之间的内存中(以进行一致的调试;这-O0实际上意味着);gcc没有尝试完全将C音译为asm的“完全哑”模式。使用tcc了点。Clang和ICC with -O0比gcc更具文字含义,MSVC调试模式也是如此。
请注意,-g永远不会对代码生成产生任何影响,而只会对发出的元数据产生影响。GCC使用其他选项(主要是-O,-f*和-m*)来控制代码生成,因此-g,除了较大的二进制文件外,您始终可以安全地启用而不损害性能。这不是调试模式(这是-O0),它只是调试符号。