我正在阅读 ODR,正如规则所说
"In the entire program, an object or non-inline function cannot have more than one definition"
,我尝试了以下操作...
文件1.cpp
#include <iostream>
using namespace std;
inline int func1(void){ return 5; }
inline int func2(void){ return 6; }
inline int func3(void){ return 7; }
int sum(void);
int main(int argc, char *argv[])
{
cout << func1() << endl;
cout << func2() << endl;
cout << func3() << endl;
cout << sum() << endl;
return 0;
}
文件2.cpp
inline int func1(void) { return 5; }
inline int func2(void) { return 6; }
inline int func3(void) { return 7; }
int sum(void) { return func1() + func2() + func3(); }
它按照规则所说起作用了。我可以有多个内联函数的定义。
创建一个函数
inline
有两件事(第二点与你的问题更相关):
这是程序员向编译器提出的建议,可以通过进行内联扩展来快速调用该函数。粗略地说,内联扩展类似于将内联函数视为宏,通过其主体的代码扩展对它的每次调用。这是一个建议 - 编译器可能不会(有时不能)执行类似的各种优化。
它将函数的范围指定为翻译单元的范围。因此,如果
inline
函数出现在 foo.cpp
中(要么因为它被写入其中,要么因为它 #include
是写入它的标头,在这种情况下,预处理器基本上会这样做)。现在您编译 foo.cpp
,可能还编译其他一些 bar.cpp
,其中也包含具有相同签名的 inline
函数(可能完全相同;可能是由于两者 #include
具有相同的标头)。当链接器链接两个目标文件时,不会被视为违反 ODR,因为 inline
指令使文件的每个副本都位于其翻译单元的本地(实际上是通过编译而创建的目标文件)。这不是建议,而是约束。这两件事同时发生并不是巧合。最常见的情况是
inline
函数出现在由多个源文件组成的头 #include
中,可能是因为程序员想要请求快速内联扩展。不过,这需要翻译单元局部性规则,这样就不会出现链接器错误。