14

在大多数情况下,如果我想在 C 中创建一个可选功能,我只需创建两个这样的函数:

#ifdef OPTIONAL_SOMETHING
void do_something(int n, const char *s)
{
    while (n--) {
        printf("%s", s);
    }

    /* ...You might get the point, really do something... */
}
#else
void do_something(int n, const char *s)
{
    /* Empty body */
}
#endif

因此,如果符号未定义(禁用该功能时),则会将一个空函数编译到可执行文件中。

深入研究程序集列表,似乎 GCC在优化被禁用时编译并调用空函数。如果启用了优化,也使用and ,它只编译必要的堆栈处理代码,但它优化了调用指令。总而言之,它保留了功能。-O2-O3

大约同样适用于非空但未使用的方法。

它应该简单地扔掉整个东西,但事实并非如此。为什么这是默认行为?只是为了好奇:我怎样才能消除这个?

4

2 回答 2

27

由于该函数具有外部链接(不是static),因此编译器无法消除它,因为另一个目标文件可能会引用它。如果函数是static,它将被完全消除。

于 2012-04-06T22:32:58.243 回答
1

如果您希望编译器最终内联您必须告诉他的函数。声明你的函数inline,这允许编译器在它认为合适的时候发出函数。

现在,当您使用 -O0 左右编译时,这可能会导致“未定义符号”错误。放一个“实例化”,如

void do_something(int n, const char *s);

仅在一个编译单元(.c 文件)中。

于 2012-04-07T03:46:11.883 回答