假设我正在使用现代版本的 GCC
来编译 C 程序。此外,考虑到我的程序包含陈旧的分支,但我非常希望这些陈旧的分支中的死代码被编译并出现在最终程序中。考虑以下程序:
int main(int argc, char** argv) {
int a = 0;
goto skip;
a = -1;
skip: ;
return a;
}
显然,如果我使用具有默认优化设置的 GCC
,第二个赋值将永远不会进入最终程序,因为编译器可以很容易地判断它永远不会被执行。假设我不希望这种情况发生。
在 GCC
中,有许多涉及死代码的标志(最著名的是 -fdce
),我可以选择在相应地调用 GCC 时显式停用这些标志:
-fno-dce
-fno-dse
-fno-tree-dce
-fno-tree-dse
据我所知,这应该指示 GCC
不要混淆第二个赋值。然而,相关代码似乎从未进入我的程序。
为什么 GCC
坚持要删除死代码,有没有办法指示 GCC 不删除第二个赋值?
最佳答案
-fno-*
选项在 gcc-4.9.2 中对我不起作用。
也就是说,我认为以下内容应该适用于所有 gcc (4.5+) 目标:
__asm__ goto (""::::no_skip);
goto skip;
no_skip:
a = -1;
skip:;
来自手册:“asm goto 语句总是隐含地被认为是可变的。”
此外,对于 gcc-4.8 及更高版本,您可以考虑添加一个属性,让编译器知道这是一条“不太可能”的路径。这有助于防止在采用“预期”路径时可能发生的分支惩罚等:
no_skip: __attribute__ ((cold));
按理说你也可以使用:
skip: __attribute__ ((hot));
关于可以指示 GCC 不消除死代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28565914/