2015-05-20 12 views
0

我知道關鍵字inline只是編譯器的提示,而不是強制的(除非使用__forceinline,例如在MSVC中)。當方法體在頭文件中時內聯被強制嗎?

在頭文件中聲明內聯函數時是否也是這種情況?編譯器會在哪個編譯單元中放置代碼?

+0

我認爲只有當方法的主體位於頭文件中時才管理內聯代碼,這只是因爲如果函數在編譯時處於C++文件中(例如可能是一個庫)內聯這樣的方法是不可能的......只有在函數聲明爲內聯並且作爲源代碼存在時,這應該是可能的(並且在某些情況下是可能的)(當頭包含在包含方法的C++文件中時被內聯) –

回答

1

該代碼將出現在全部包含此標頭的編譯單元中。 inline的要點是向鏈接器說這個函數可以在多個目標文件中找到,並且這些拷貝中的任何一個都可以由鏈接器選擇。

2

inline不只是提示編譯器。

內聯函數可以用多個翻譯單元定義,並且所有這些定義將具有相同的類型,地址和定義。

如果一個函數是在一個頭中定義的,那麼它必須聲明爲inline,否則當它被包含在多個翻譯單元中時,它將違反一個定義規則。

內聯函數可以是:

  1. 在全局範圍的函數可以使用關鍵字inline聲明內聯。
  2. 完全在class/struct/union定義中定義的函數,無論是成員函數還是非成員好友函數,都始終是內聯的。
  3. 聲明爲constexpr的函數始終是內聯的。

source

是它也如此[即inline是一個暗示]聲明在標頭中的內聯函數時?

是的。 inline關鍵字是總是提示編譯器執行「內聯」。

但是,請注意,這只是一個提示。編譯器可以自由地忽略它(還有很多)。

編譯器能夠執行內聯函數內聯的真正原因是整個定義是可用的。您會注意到與static函數和實例化的函數模板相同。

編譯單元將在哪個編譯器中放置代碼?

在鏈接之前,內聯函數將在任何定義它的編譯單元中完全定義。它將被完整地編譯到每個目標文件中。

在鏈接期間,鏈接器將確定要使用哪個定義,並放棄所有其他定義。

另請參閱this question及其答案。

0

內聯不是強制的,永遠。如果你在類定義中定義了一個方法,它將被隱式地內聯。這就像在類定義之外定義它,除了內聯暗示。這與定義所在的文件無關。

當您請求的內聯函數沒有實際內聯時,由編譯器決定將它放在哪裏。在早期,您可以在包含頭文件的每個文件中獲得一個非導出副本。現在,將某種策略應用於將它與第一個構造函數,第一個方法放在同一位置,或者將虛擬函數表是。它依賴於編譯器。

相關問題