如果我将.h文件中的函数定义为
会发生什么extern int returnaint(void);
,在相关的.c文件中将其定义为
inline int returnaint(void) {
return 1;
}
并在另一个.c文件中包含标题并使用该函数?当我单独编译这些东西时,为每个.c文件创建一个目标文件然后链接它们,包括内联函数,或者会发生什么?
我知道编译器可以忽略inline
,但如果它在这种情况下不忽略它会怎么样?
答案 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标志进行编译。