C99内联函数在.c文件中

时间:2013-04-26 21:29:41

标签: c c99

我在.c(没有标头声明)中定义了我的函数,如下所示:

inline int func(int i) {
 return i+1;
}

然后在下面的同一个文件中我使用它:

...
i = func(i);

在链接过程中,我得到了“未定义的'func'引用”。为什么呢?

3 个答案:

答案 0 :(得分:42)

C99中的inline模型与大多数人的想法略有不同,特别是与C ++使用的模型不同

inline只是一个提示,编译器不会抱怨双重定义的符号。如果需要,它不保证函数内联,也不保证生成符号。要强制生成符号,您必须在 inline定义之后添加一种实例化

int func(int i);

通常,您在头文件中有inline定义,然后包含在几个.c文件(编译单元)中。并且您只在其中一个编译单元中拥有上述行。您可能只看到了问题,因为您没有对编译器运行使用优化。

因此,在.c文件中使用inline的用例没有多大意义,最好只使用static,即使是额外的inline也没有给你买得多。

答案 1 :(得分:31)

C99内联语义经常被误解。 inline说明符有两个目的:

首先,作为static inlineextern inline声明的编译器提示。如果删除说明符,语义将保持不变。

其次,在原始inline(即没有staticextern)的情况下,提供内联定义作为外部定义的替代,必须存在于不同的翻译单位。不提供外部行为是未定义的行为,通常表现为链接失败。

如果您希望将函数放入共享库,但是也可以使函数体可用于优化(例如内联或专门化),这将非常有用。假设一个足够智能的编译器,这使您可以恢复C ++模板的许多好处,而无需跳过预处理器箍。

请注意,它比我在这里描述的更麻烦,因为有另一个文件范围非内联外部声明将触发Jens回答中描述的第一种情况,即使定义本身是inline而不是{ {1}}。这是设计使得你可以在头文件中有一个内联定义,你可以通过为外部声明添加一行来包含到提供外部文件的源文件中。

答案 2 :(得分:0)

这是因为GCC处理内联函数的方式。 GCC执行内联替换作为优化的一部分

要消除此错误,请在内联之前使用staticstatic关键字强制编译器使用static关键字强制编译器采用此内联函数,从而使程序成功编译。

static inline int func(int i) {
 return i+1;
}
...
i = func(i);