假设我使用现代版本的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 不摆脱第二次分配?
答案 0 :(得分:9)
使用gcc-4.9.2,-fno-*
选项对我不起作用。
也就是说,我认为以下所有gcc(4.5+)目标都应该是可移植的:
__asm__ goto (""::::no_skip);
goto skip;
no_skip:
a = -1;
skip:;
从手册中:“asm goto语句总是被隐含地视为volatile。”
此外,使用gcc-4.8及更高版本,您可以考虑添加一个属性,让编译器知道这是一个“不太可能”的路径。这有助于防止在采用“预期”路径时可能发生的分支处罚等:
no_skip: __attribute__ ((cold));
按理说你也可以使用:
skip: __attribute__ ((hot));