可以指示 GCC 不消除死代码吗?

标签 c gcc

假设我正在使用现代版本的 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/

相关文章:

c - 在 GCC 中以编程方式调用调试器

c++ - 如何强制 Eclipse 使用 g++ 而不是 gcc?

c++ - 空闲时间后 libcurl 奇怪崩​​溃

c - 在结构数组中搜索函数 - 停止条件未知

c - Objective-C UTF-8 和 UTF-16 字符串(以字节表示)的差异

c - 阅读双倍时的 scanf 问题

c++ - Lambda 语法或 gcc 错误的最后一刻更改?

c++ - C/C++ - 查询依赖于平台的换行符(用于内存映射文件)

c - C 中的链表,未正确链接

c - 按字符串对结构体数组进行排序