[英]Does inline determine internal linkage?
我正在尝试extern一个内联函数。 我认为它应该如何工作:
//a.cpp
inline void f(int) {}
//b.cpp
extern void f(int);
int main() { f(4); }
但是获得链接错误。 然后通过读这个 (“1)它必须声明inline
在每一个翻译单元”)。 我尝试过的:
//a.cpp
inline void f(int) {}
//b.cpp
extern inline void f(int);
int main() { f(4); }
仍然得到链接错误。 但现在,尝试一些我不知道自己在做什么的事情:
//a.cpp
extern inline void f(int) {}
//b.cpp
extern inline void f(int);
int main() { f(4); }
有用。 这里发生了什么事? 在将extern
添加到所有内容之前, a.cpp
f
a.cpp
具有内部链接?
我正在使用MSVC 2017(v141)和/permissive-
和/std:c++17
我正在尝试extern一个内联函数。
没有理由使用extern
功能。 查看存储持续时间 - 链接 。 函数默认具有外部链接; 为了不具有外部链接,需要做一些特殊的事情(即将它放在匿名命名空间中或将其声明为static
)。 因此,内联函数的正常使用已经展示了外部链接,而不需要extern
关键字。
我认为它应该如何工作:
//a.cpp inline void f(int) {} //b.cpp extern void f(int); int main() { f(4); }
然后通过读这个 (“1)它必须声明
inline
在每一个翻译单元”)。
该引用是正确的,但在它所说的“内联函数[...]的定义必须存在于访问它的翻译单元中时,请查看更多内容[...]。” 您的示例在b.cpp
声明了f
,但不是定义。 如果要从b.cpp
调用f
,则需要该转换单元中的完整定义,如下所示:
inline void f(int) {}
(这与a.cpp
中存在的代码相同。)如果你不使用大括号,那么你有一个声明但没有定义,从而使从该翻译单元调用f
是非法的。
基本上,在头文件外定义内联函数真的很痛苦,除非你给它内部链接。 这是因为使用内联函数的每个源文件都需要自己的函数体副本,这意味着如果更改函数,则需要在多个文件中进行更改。 钱币。 不要这样做。 在头文件中定义每个inline
函数。 如果您认为要在源文件中定义一个,则可能会误解“ inline
”的含义。
“ inline
”是什么意思?
就编译器而言, inline
关键字意味着(几乎)没有。 它只是函数定义上的一个标志,它被传播到目标代码中,以便链接器可以看到它。 编译器处理函数就像处理任何其他函数一样。 该函数可以被正常调用,或者可以内联调用 - 就像任何其他函数一样。
编译器可能inline
标志执行某些操作的一种情况是在使用inline
函数声明函数时,但缺少定义。 这是在链接器接管之前可以捕获的错误。 它没有被编译器捕获,但它可以。 (如果没有被编译器捕获,它将被链接器捕获。)
继续前进到链接阶段。 当链接器看到inline
标志时,它会挂起该函数的单定义规则。 链接器期望在编译器优化之后仍然使用该函数的每个转换单元中看到函数的定义。 它可以选择其中任何一个定义作为最终实现。 因此,所有定义必须匹配的原因。
这就是它。 inline
关键字基本上意味着函数定义在头文件中。 它告诉链接器在多个翻译单元中出现该定义时不会抱怨,因为这是预期的。
回到问题,看起来意图是声明一个inline
函数,其定义只出现在一个翻译单元中。 换句话说,该函数将被标记为在多个翻译单元中定义,但该定义仅在一个中。 那里有点不一致,如果不是完全矛盾的话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.