外部内联函数会发生什么?

时间:2013-07-06 15:24:19

标签: c compiler-construction header linker inline

如果我将.h文件中的函数定义为

会发生什么
extern int returnaint(void);

,在相关的.c文件中将其定义为

inline int returnaint(void) {
    return 1;
}

并在另一个.c文件中包含标题并使用该函数?当我单独编译这些东西时,为每个.c文件创建一个目标文件然后链接它们,包括内联函数,或者会发生什么?

我知道编译器可以忽略inline,但如果它在这种情况下不忽略它会怎么样?

3 个答案:

答案 0 :(得分:24)

inline添加到.c文件中的函数定义只是多余的。

  • .c文件的编译单元会看到extern声明(不含inline)和inline定义。因此,它会在目标文件中发出函数的符号。

  • 所有其他编译单元只能看到extern声明,因此如果您将最终可执行文件与其他.o文件链接,他们可以毫无问题地使用该函数。

事实上,你只是错误的方式。此功能旨在用于inline文件中的.h定义,对所有人都可见。该函数的定义仅作为符号的声明,就像extern一样,但不定义它。

只有一个extern文件(编译单元)中的.c声明确保在那里定义符号。

术语有点令人困惑,inline 定义充当符号的声明,extern 声明充当定义它

答案 1 :(得分:5)

它不会编译。来自C11(ISO / IEC 9899:2011)§6.7.4函数说明符(强调添加):

  

任何具有内部链接的函数都可以是内联函数。用于外部功能   链接,以下限制适用:如果使用内联函数说明符声明函数,则它也应在同一个转换单元中定义。如果所有的   翻译单元中函数的文件范围声明包括内联函数   没有extern的说明符,那么该翻译单元中的定义是内联的   定义。内联定义不提供函数的外部定义,   并且不禁止在另一个翻译单元中使用外部定义。内联定义   提供了外部定义的替代方案,翻译人员可以使用该定义来实现   在同一翻译单元中对该功能的任何调用。没有具体说明是否打电话给   函数使用内联定义或外部定义。 140)

     

140)由于内联定义与相应的外部定义和任何其他定义不同   其他翻译单元中的相应内联定义,所有具有静态存储的对应对象   持续时间在每个定义中也是不同的。

另一个.c文件只从标题中获取inline函数的声明,但不是定义,因此它与粗体字的规则相反。

修改

正如@Jens Gustedt指出的那样,我之前的解释是错误的,因为在OP的问题中,该函数在头文件中被声明为非内联:

extern int returnaint(void);

因此,另一个.c文件会将其视为普通函数。

答案 2 :(得分:0)

我们只是遇到了类似的问题,仅在.c文件中保持内联即可解决警告问题。在具有和不具有函数定义的两个文件中,也都发生了加速。使用-o3标志进行编译。