2009-10-21 75 views
1

在的內聯函數在維基百科的問題: http://en.wikipedia.org/wiki/Inline_expansion#Problems混淆inline函數的問題

它說:「#語言規範可以讓一個程序來做出有關參數的附加假設,程序,它可以不再在程序內聯後製作。「

有人可以詳細說明這一點嗎?

如何防止GCC內嵌C++函數?

+1

「你如何防止GCC內聯C++函數?」通常情況下,這是一個錯誤的問題。正確的問題經常是「爲什麼要阻止GCC內嵌C++函數?」 – sbi 2009-10-21 15:29:42

+0

我相信原因與別名有關。當只調用一個函數時,編譯器可以忽略調用函數中的指針,該指針可能會替代被調用函數中指向的對象。內聯時,被調用函數的代碼與調用函數中的代碼在同一個塊中執行,並且別名成爲問題。 – 2009-10-21 15:36:06

+0

@litb,我還沒有看到它。我們能看到一個具體的例子嗎? – 2009-10-21 16:39:07

回答

5

在C++中,inline關鍵字實際上只具有一個需要含義:表示一定義規則被暫停該功能(例如,功能可以以若干翻譯單元所定義,和碼仍符合)。

具體而言,使用inline關鍵字不能確保該函數的代碼將以內聯方式生成。在類定義中定義一個函數也會使它成爲一個內聯函數 - 但是,這又不能確保它的代碼會以內聯的方式生成。

相反,一個在類定義之外定義的函數,如果沒有inline關鍵字,它可以並且仍然可以內聯地生成它的代碼。唯一的區別是,在這種情況下,該函數的多個定義會導致代碼不一致。

底線是便攜式代碼不能保證代碼是或不是內嵌生成的。但是,如果您不介意讓代碼不可移植,則可以使用__attribute__(noinline)

但是,我不會在維基百科引用的引用的基礎上做到這一點。維基百科幾乎不是一個權威的來源,即使是這樣,即使是這樣,你所引用的只是對某些假設條件下某些假設編譯器的假設語言會發生什麼的模糊聲明。編寫代碼清晰易讀並且讓編譯器擔心從中產生好的結果會更好。

-2

關於如何內聯函數,C/C++是非常明確的。所以維基百科的特別評論不適用於這些語言。假設C語言規範要求函數調用參數以相反的順序在堆棧上傳遞(編輯:並且堆棧總是向下生長,並且在參數之間沒有填充)。實際上他們通常都是,但是你不能認爲這是真的。下面的代碼在這個奇怪的世界中是有效的。

void foo(int i, int j) 
{ 
    int myi = &j[1]; 
    return myi + j; 
} 

如果foo裏面出現的整數發生在棧上面,j可能不是i。

+2

-1在任何現實中,此代碼的結果未在C++規範中定義。很難看出你的回答將如何幫助提問者獲得內聯關鍵字的使用/誤用清晰度。 – Elemental 2009-10-21 16:23:36

+0

問題是兩個部分。澄清「語言規範」評論以及如何在C++中禁用內聯。維基百科的「language specificaiton」評論不適用於c/C++,所以我發明了一個類似於C的語言。我絕不會聲稱我寫的是有效的C++甚至c。我試圖用「假設」和「在這個陌生的世界」 – 2009-10-21 16:30:57

1

inline關鍵字是對編譯器的建議或刺激。維基百科的定義似乎意味着,通過使用這種類型的關鍵字,您可以限制您可以使用該功能執行的操作。例如,你可能認爲不可能獲取內聯函數的地址。 C++編譯器會採取相反的方法,即使函數被標記爲內聯,如果代碼中的某個地方使用了該函數的地址,那麼該函數並不是內聯生成的。

同樣,如果一個函數是虛擬的(顯然)不能內聯生成,但仍然不能使多態函數的內聯定義非法。

也許我在這裏寫的內容將讓您深入瞭解編譯器需要如何用Coffin雄辯地表達的內聯關鍵字。