Osc*_*son 3 c optimization gcc inline gcc6
我最近遇到了在升级 debian 测试后编译一段代码的问题,得到了 gcc 6.2.1 编译器。我把它归结为这个简单的例子:
inline int func(void) {
return 0;
}
int main (int argc, char **argv) {
func();
}
Run Code Online (Sandbox Code Playgroud)
该代码不会不与下面的编译:
gcc -o exec code.c # gcc 6.2.1
它失败了:
undefined reference to 'func'
我也在同一台主机上尝试过 gcc 4.8、4.9 和 5,但都失败了。如果我添加,它会编译:
gcc -o exec code.c -O2 # gcc 6.2.1
我真的很好奇为什么它与 -O2 标志一起工作,但不是没有,我希望这能工作?
将“-O”选项添加到您的编译器命令中。内联仅在启用优化时打开。
C99 内联函数
默认情况下,Clang 以 GNU C11 模式构建 C 代码,因此它对 inline 关键字使用标准 C99 语义。这些语义与 GNU C89 模式中的语义不同,后者是 5.0 之前 GCC 版本中的默认模式。例如,考虑以下代码:
inline int add(int i, int j) { return i + j; }
int main() {
int i = add(4, 5);
return i;
}
Run Code Online (Sandbox Code Playgroud)
在 C99 中,内联意味着函数的定义仅用于内联,并且在程序的其他地方还有另一个定义(没有内联)。这意味着这个程序是不完整的,因为如果 add 没有被内联(例如,在没有优化的情况下编译时),那么 main 将有一个对其他定义的未解析引用。因此,我们会得到一个(正确的)链接时错误,如下所示:
Undefined symbols:
"_add", referenced from:
_main in cc-y1jXIr.o
Run Code Online (Sandbox Code Playgroud)
相比之下,GNU C89 模式(在旧版 GCC 中默认使用)是 C89 标准加上许多扩展。C89 没有内联关键字,但 GCC 将其识别为扩展并仅将其视为对优化器的提示。
有几种方法可以解决这个问题:
所有这些仅适用于 C 代码;C++ 中 inline 的含义与其在 GNU89 或 C99 中的含义大不相同。