我最近遇到了在升级debian测试后编译一段代码,获得gcc 6.2.1编译器的问题。我把它归结为这个简单的例子:
inline int func(void) {
return 0;
}
int main (int argc, char **argv) {
func();
}
代码不使用以下代码进行编译:
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标志,但不是没有,我希望这有用吗?
答案 0 :(得分:3)
添加" -O"编译器命令的选项。仅在启用优化时才会启用内联。
C99内联函数
默认情况下,Clang在GNU C11模式下构建C代码,因此它对内联关键字使用标准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;
}
在C99中,内联意味着函数的定义仅用于内联,并且程序中的其他位置还有另一个定义(没有内联)。这意味着这个程序是不完整的,因为如果add没有内联(例如,在没有优化的情况下进行编译时),那么main将有一个未解析的对该另一个定义的引用。因此,我们会得到(正确的)链接时错误,如下所示:
Undefined symbols:
"_add", referenced from:
_main in cc-y1jXIr.o
相比之下,GNU C89模式(在旧版本的GCC中默认使用)是C89标准加上许多扩展。 C89没有内联关键字,但GCC将其视为扩展,只是将其视为优化器的提示。
有几种方法可以解决此问题:
所有这些仅适用于C代码; C ++中inline的含义与它在GNU89或C99中的含义非常不同。