2016-09-23 75 views
5

我读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(); } 

它的工作原则如下。我可以有多个内联函数的定义。

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

他引用的内容表示一个对象或*非内联函数不能有多个定义。 –

回答

7

制作功能inline做了两件事(第二点是更贴近您的问题):

  1. 这是一个建议由程序员的编译器,以使该功能快速调用,可能通过内联扩展。粗略地说,内联扩展类似于像宏一样处理内联函数,通过它的主体代码扩展每个对它的调用。这是一个建议 - 编译器可能没有(有时不能)执行各种优化。

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

这两件事合在一起并不是巧合。最常见的情况是inline函数在多个源文件中出现在头文件#included中,可能是因为程序员想要请求快速内联扩展。然而,这需要翻译单元地点规则,以避免链接器错误。