我有这个包含大量内联函数的头文件,编译后说: 函数***的多重定义,看起来像这样的函数:
inline int testab(int a, int b)
{
return a>b;
}
在内联前添加静态后,错误消失了。这是正确的方法吗?或者我错过了什么?我以为我可以在这样的标题中设置内联函数。
答案 0 :(得分:7)
inline
与否,一旦标题被复制到至少两个文件中,就无法再链接文件了。
您可以在标头中安全地实现功能的唯一方法是使用static
。这样,函数的每个副本对其他副本都是不可见的。
请注意,将它们一起使用没有任何限制,因此您可以安全地编写:
static inline bool testab(int a, int b)
{
return a>b;
}
inline
告诉编译器你认为该函数足够小以便内联。那就是你告诉编译器你不认为内联函数的额外空间与它的(轻微的)(可能的)性能增益相反。然而,大多数编译器都足够智能,可以自行决定使用您的关键字,只需倾向于更多内联,而不一定总能听取您的意见。当然,这取决于编译器。有些编译器可能会完全忽略关键字。
static
意味着无论定义静态变量的范围如何,它都将在其外部不可见。如果函数中有static
变量,它将在其外部不可见。如果文件中有static
变量(即静态全局变量),它将在其外部不可见,这意味着在编译链接器以查看并混淆之后符号不存在。这就是为什么,如果你编写了一个库,其中有全局变量或函数不应该在库外可见,你应该将它们声明为static
。
显然,根据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。