2016-09-23 29 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中,可能是因爲程序員想要請求快速內聯擴展。然而,這需要翻譯單元地點規則,以避免鏈接器錯誤。