19

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

extern int returnaint(void);

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

inline int returnaint(void) {
    return 1;
}

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

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

4

2 回答 2

32

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

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

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

事实上,你只是把它弄错了。此功能旨在用于您在文件中具有对所有人可见的inline定义。.h该函数的定义仅充当符号的声明,就像extern将要的那样,但没有定义它。

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

术语有点混乱,inline 定义充当符号的声明,而extern 声明充当符号的定义

于 2013-07-06T18:26:42.997 回答
6

它不会编译。从 C11 (ISO/IEC 9899:2011) §6.7.4功能说明符(强调添加):

任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,适用以下限制:如果函数使用内联函数说明符声明,则它也应在同一翻译单元中定义。如果翻译单元中函数的所有文件范围声明都包含不带 extern 的内联函数说明符,则该翻译单元中的定义是内联定义。内联定义不为函数提供外部定义,也不禁止在另一个翻译单元中进行外部定义。内联定义提供了外部定义的替代方案,翻译器可以使用它来实现对同一翻译单元中函数的任何调用。未指定对函数的调用是使用内联定义还是外部定义。140)

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

另一个.c文件只从头文件中获取inline函数的声明,而不是定义,因此它违反了粗体的规则。

编辑:

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

extern int returnaint(void);

因此,其他.c文件会将其视为正常功能。

于 2013-07-06T15:37:29.033 回答