簡體   English   中英

內聯是否確定內部聯系?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM