一个extern inline函数会发生什么?

24

如果我在我的 .h 文件中定义函数会发生什么

extern int returnaint(void);

在相关的.c文件中进行定义

inline int returnaint(void) {
    return 1;
}

如果我在一个.c文件中编写一个内联函数,并在另一个.c文件中包含头文件并使用该函数,当我单独编译这些内容时,为每个.c文件创建一个目标文件,然后链接它们,这个内联函数是否被包含了?或者会发生什么?

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


2
然后你会得到一个链接器错误。 - user529758
2
@H2CO3,不会出现链接错误。具有inline定义的编译单元也会看到extern声明,因此必须发出符号。请参见我的答案。 - Jens Gustedt
2
请注意,inline的语义仅在c99中定义,并且某些编译器(例如gcc)仍默认为c89。http://www.greenend.org.uk/rjk/tech/inline.html提供了一个很好的摘要和指南,介绍如何根据您想要支持的编译器标准来使用inline。 - Uwe Kleine-König
1
可能是 extern inline 的重复问题。还请参阅静态内联、外部内联和普通内联函数之间的区别是什么?,以及Jonathan Wakely在GCC邮件列表上的回答:关于内联函数的未定义错误 - jww
2个回答

39

.c 文件的函数定义中添加 inline 只是徒劳无功。

  • 你的 .c 文件编译单元看到了一个没有 inline 关键字的 extern 声明和一个 inline 定义。于是它在目标文件中产生了该函数的符号。

  • 所有其他编译单元只看到了一个 extern 声明,所以如果你将最终可执行文件与其他 .o 文件链接,它们就可以无问题地使用该函数。

实际上,你只是将其搞错了。这个特性是为了让你在 .h 文件中拥有 inline 定义,对每个人都可见。该函数的这个定义仅充当符号的声明,就像 extern 一样,但并不定义它。

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

术语有点混淆,inline定义 充当符号的声明,extern声明 则定义了它。


2
好观点。我认为我应该将我的内联函数移到头文件中! :-) - musicmatze
1
在定义函数的翻译单元中添加内联将产生影响。可能的结果是,该编译单元中对该函数的使用将被内联。 - Uwe Kleine-König
1
@UweKleine-König,不对。编译器可以随意操作。如果函数定义是可见的,编译器可能选择或者不选择内联,只要它遵循“as-if”规则即可。在该定义中添加“inline”并不会改变任何东西。 - Jens Gustedt
3
我使用的编译器主要是gcc,也会用clang或icc,使用inline关键字对它们来说并没有什么区别,它们甚至不会将其视为提示。如果想让它们相信你比它们更懂,你需要使用一些编译选项或使用__attribute__((allways_inline))来改变情况。因此,不要期望仅仅添加inline就会产生任何变化。 - Jens Gustedt
1
@YoYoYonnY,编程术语不容易掌握。也许我修改后会更好,现在呢? - Jens Gustedt
显示剩余8条评论

4
无法编译。来自C11(ISO / IEC 9899:2011)§6.7.4函数说明符(强调添加):
任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,以下限制适用:如果使用内联函数说明符声明一个函数,则它也必须在同一翻译单元中进行定义。如果翻译单元中一个函数的所有文件范围声明都包括不带extern的内联函数说明符,则该翻译单元中的定义就是内联定义。内联定义不提供函数的外部定义,并且不禁止在另一个翻译单元中进行外部定义。内联定义提供了一种替代外部定义的方式,翻译器可以在同一翻译单元中使用它来实现对函数的任何调用。调用该函数时使用内联定义或外部定义是未指定的。140)

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

另一个 .c 文件仅从头文件获取 inline 函数的声明,但没有获得定义,因此违反了粗体字规则。 编辑: 如@Jens Gustedt所指出,我的先前解释是错误的,因为在OP问题中,该函数在头文件中被声明为非内联。
extern int returnaint(void);

所以另一个.c文件会将其视为普通函数。

14
答案错误。其他的 .c 文件看不到 .h 中的 inline 声明,因为该头文件中只有 extern 而没有 inline - Jens Gustedt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接