我正在尝试外部内联函数。
没有理由使用extern
有一个函数。看存储期限-联动 https://en.cppreference.com/w/cpp/language/storage_duration#Linkage。函数默认具有外部联动;为了没有外部链接,需要做一些特殊的事情(即将它放在匿名名称空间中或声明它static
)。因此,内联函数的正常使用已经表现出外部链接,而不需要extern
关键词。
我认为它应该如何工作:
//a.cpp
inline void f(int) {}
//b.cpp
extern void f(int);
int main() { f(4); }
然后通过阅读this https://en.cppreference.com/w/cpp/language/inline ("1)必须声明inline
在每个翻译单元中。").
该参考文献是正确的,但请多查找一下它说的地方“内联函数的定义 [...] 必须存在于访问它的翻译单元中 [...]。”您的示例有一个声明f
in b.cpp
,但不是定义。如果你要打电话f
from b.cpp
,您需要该翻译单元中的完整定义,如下所示:
inline void f(int) {}
(这与存在于a.cpp
.) 如果省略大括号,则有一个声明,但没有定义,因此调用是非法的f
来自那个翻译单位。
基本上,在头文件外部定义内联函数确实很痛苦,除非您给它内部链接。这是因为使用内联函数的每个源文件都需要自己的函数体副本,这意味着如果更改函数,则需要在多个文件中进行更改。钱币。不要这样做。定义你的每一个inline
头文件中的函数。如果您认为要在源文件中定义一个,您可能会误解什么“inline
" means.
什么是“inline
" mean?
就编译器而言,inline
关键字(几乎)没有任何意义。它只是函数定义上的一个标志,传播到目标代码中,以便linker看到它。编译器处理该函数就像处理任何其他函数一样。该函数可以正常调用,也可以内联调用它——就像任何其他函数一样。
编译器可能会执行某些操作的一种情况inline
flag 是函数被声明的时间inline
,已使用,但缺乏定义。这是一个可以在链接器接管之前捕获的错误。它不是have被编译器捕获,但它可以。 (如果没有被编译器捕获,它将被链接器捕获。)
进入链接阶段。当链接器看到inline
标志,它暂停该函数的单一定义规则。链接器期望在编译器优化后仍然使用该函数的每个翻译单元中看到该函数的定义。它可以选择这些定义中的任何一个作为最终的实现。因此,所有定义都必须匹配。
就是这样。这inline
关键字基本上意味着函数定义位于头文件中。它告诉链接器当该定义出现在多个翻译单元中时不要抱怨,因为这是预期的。
回到问题,看起来意图是宣布inline
其定义仅出现在一个翻译单元中的函数。换句话说,该函数将被标记为在多个翻译单元中定义,但定义将仅在一个翻译单元中。即使不是完全矛盾,也有些不一致。