7

gcc 是否完全符合 C99 标准中规定的内联模型?

我浏览了一些关于这个问题的信息。但我不明白为什么必须用“extern”或“static”指定内联函数。

在 .c 文件中,调用在同一翻译单元中定义的内联函数会导致错误。编译器行为的原因是什么?

我发现了一篇文章没有“静态”或“外部”的“内联”在 C99 中有用吗?

这是什么意思?

如果在可见内联定义的情况下调用具有外部链接的某个函数 func,则行为与调用具有内部链接的另一个函数(例如 __func)相同。

4

3 回答 3

11

我不得不承认,C99 中的内联语义有点令人困惑。inline量词允许您定义函数的替代定义。

如果一个函数在任何地方都被定义为只是inline在声明和定义中,那么这个定义只在本地翻译单元中有效。在 C99 标准中,这个定义非常模糊,但实际上大多数编译器以与static inline. 本质上只是inline覆盖任何其他链接单元中具有相同名称的任何其他函数。因此,如果您将函数声明为仅inline在标头中,编译器将期望在同一编译单元中找到它的定义,如果没有,稍后会给您一个错误。

现在,如果一个函数既可以内联又可以在其他翻译单元中使用,那么它需要extern在头声明中定义。然后编译器不会只在当前编译单元中查找它。

static inline是目前最便携的定义,并且受限于当前的翻译单元。这通常与实际的函数定义一起出现在标题中。

于 2013-09-05T12:30:46.190 回答
8

inline函数属于头文件,这样所有编译单元都可以看到代码。

如果由于某种原因无法内联代码,则最终的可执行文件必须具有它可能链接到的函数的一个版本。这你必须在一个编译单元(.c 文件)中“实例化”类似的东西

extern inline void toto(int bla);

这会强制将符号包含在该单元中。

您可以在这里找到更多相关信息

于 2013-09-05T12:27:19.833 回答
-1

您必须考虑代码如何链接。首先将源代码编译为目标文件。这些目标文件只包含每个函数的二进制代码,这些代码是通过索引函数的名称(或 c++ 中的损坏名称)找到的。目标文件不包含有关函数是否内联的信息。所以在链接过程中必须将这些信息放入头文件中,与目标文件结合使用。通过在文件static的前面使用,您可以使该函数对在编译过程之前使用该函数的任何其他函数可见。但是一旦这些函数被编译到一个目标文件中,它们就不能与来自其他目标文件的其他函数“内联”。inline.cstatic inline

因此,只需在头文件定义 ( file) 中而不是源文件 ( ) 中包含inline关键字,您就可以在链接过程中将来自一个目标文件的函数“内联”到来自另一个目标文件的其他函数中。.h.c

于 2017-09-15T14:04:33.617 回答