在我声明函数内联后,什么可能再次导致多个定义错误?

时间:2011-12-14 09:06:32

标签: c gcc header inline

我有这个包含大量内联函数的头文件,编译后说: 函数***的多重定义,看起来像这样的函数:

inline int testab(int a, int b)
{
        return a>b;
}

在内联前添加静态后,错误消失了。这是正确的方法吗?或者我错过了什么?我以为我可以在这样的标题中设置内联函数。

2 个答案:

答案 0 :(得分:7)

inline与否,一旦标题被复制到至少两个文件中,就无法再链接文件了。

您可以在标头中安全地实现功能的唯一方法是使用static。这样,函数的每个副本对其他副本都是不可见的。

请注意,将它们一起使用没有任何限制,因此您可以安全地编写:

static inline bool testab(int a, int b)
{
        return a>b;
}

编辑:更多详情

inline告诉编译器认为该函数足够小以便内联。那就是你告诉编译器你不认为内联函数的额外空间与它的(轻微的)(可能的)性能增益相反。然而,大多数编译器都足够智能,可以自行决定使用您的关键字,只需倾向于更多内联,而不一定总能听取您的意见。当然,这取决于编译器。有些编译器可能会完全忽略关键字。

另一方面,

static意味着无论定义静态变量的范围如何,它都将在其外部不可见。如果函数中有static变量,它将在其外部不可见。如果文件中有static变量(即静态全局变量),它将在其外部不可见,这意味着在编译链接器以查看并混淆之后符号不存在。这就是为什么,如果你编写了一个库,其中有全局变量或函数不应该在库外可见,你应该将它们声明为static

编辑2:更正

显然,根据this回答,inline函数不应为链接器导出其标识符。尽管如此,人们可以将static附加到它上面,只是为了使其更清晰。显然,一些编译器仍会导出标识符,因此在这些情况下static确实是必要的。

答案 1 :(得分:0)

如果在头文件中定义函数,则需要指定static,否则为函数创建多个符号表定义(每个.c文件中有一个),并且当您尝试链接相应的函数时会发生碰撞目标文件。 要在标题中定义内联函数,我相信您需要:

static inline int foo(int x) __attribute__((always_inline))
    {
    return x+1;
    }

不确定这是否正确;见:http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Inline.html#Inline