一个定义规则 - 内联函数的多个定义

时间:2016-09-23 04:55:42

标签: c++ c++11

我正在阅读ODR,正如规则"In the entire program, an object or non-inline function cannot have more than one definition"所述,我尝试了以下内容......

file1.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;
}

file2.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(); }

按规则说法有效。我可以有多个内联函数的定义。

  • 非内联函数链接和内联函数链接有什么区别?
  • 链接器如何区分这两者?

1 个答案:

答案 0 :(得分:6)

制作函数inline会做两件事(第二点与您的问题更相关):

  1. 程序员建议编译器快速调用此函数,可能是通过内联扩展。粗略地说,内联扩展类似于将内联函数视为宏,通过其主体代码扩展每个调用。这是建议 - 编译器可能不会(有时也不会)执行各种优化。

  2. 它指定函数的范围是翻译单元的范围。因此,如果inline函数出现在foo.cpp中(因为它写在其中,或者因为它#include是一个写入它的标题,在这种情况下预处理器基本上是所以)。现在你编译foo.cpp,也可能还有一些其他bar.cpp,它们还包含一个具有相同签名的inline函数(可能完全相同;可能是由于#include相同的标题)。当链接器链接两个目标文件时,它不会被视为违反ODR,因为inline指令使文件的每个副本都在其翻译单元本地(通过编译创建的目标文件,有效地) 。这不是建议,而是绑定

  3. 将这两件事放在一起并非巧合。最常见的情况是inline函数出现在标题#include d中的几个源文件,可能是因为程序员想要请求快速内联扩展。但这需要翻译单元局部性规则,因此不应出现链接器错误。