最近我在项目中遇到了一个问题。我通常在 gcc-4 中编译它,但在尝试在 gcc-3 中编译后,我注意到对内联函数的不同处理。为了说明这一点,我创建了一个简单的示例:
主.c:
#include "header.h"
#include <stdio.h>
int main()
{
printf("f() %i\n", f());
return 0;
}
文件.c:
#include "header.h"
int some_function()
{
return f();
}
头文件.h
inline int f()
{
return 2;
}
当我在 gcc-3.4.6 中编译代码时:
gcc main.c file.c -std=c99 -O2
我得到链接器错误(f 的多个定义),如果我删除-O2
标志也是一样的。我知道编译器不需要内联任何东西,所以我假设它把 f 放在目标文件中,而不是在main.c
and的情况下内联它file.c
,因此是多重定义错误。显然我可以通过制作f
静态来解决这个问题,然后,在最坏的情况下,f
在二进制文件中有几个 's。
但我尝试在 gcc-4.3.5 中编译这段代码:
gcc main.c file.c -std=c99 -O2
一切正常,所以我假设f
在这两种情况下都内联了较新的 gcc,并且二进制文件中根本没有函数f
(在 gdb 中检查,我是对的)。
但是,当我删除该-O2
标志时,我得到了两个未定义的int f()
. 在这里,我真的不明白发生了什么。似乎 gcc 假定f
会被内联,因此它没有将其添加到目标文件中,但后来(因为没有-O2
)它决定生成对这些函数的调用而不是内联,这就是链接器错误的来源。
现在问题来了:我应该如何定义和声明我想要内联的简单和小函数,以便它们可以在整个项目中使用而不用担心各种编译器中的问题?将它们全部设为静态是正确的做法吗?或者也许 gcc-4 坏了,我不应该在几个翻译单元中有多个内联函数定义,除非它们是静态的?