2012-10-11 129 views
23

任何人都可以告訴我內聯函數和靜態內聯函數有什麼區別嗎?內聯函數和靜態內聯函數之間的區別

在哪些情況下我應該更喜歡靜態內聯,而不是內聯?

我在問這個問題,因爲我有一個內聯函數,在鏈接期間我正面臨編譯問題(relocation error:... symbol has been discarded with discarded section ...)。我使它成爲一個正常的功能,它工作。 現在我的一些老年人告訴我用靜態內聯嘗試。 以下是我的功能:

inline void wizSendNotifier (const char* nn_name, bpDU* arg=0, int aspect = -1) 
{ 
    wizuiNotifier* notifier = ::wizNtrKit.getNotifier (nn_name); 
    notifier->notify (arg, aspect); 
} 

而這不屬於課內。這是在一個頭文件中!

我想對一個靜態函數的調用應該只在它定義的特定TU中完成。

由於我的函數是在一個頭文件中,並且如果我將它設置爲靜態的,是否會將包含該頭文件的靜態函數用於該翻譯單元的情況包含在哪裏?

+0

這個函數在類中嗎?也請張貼其聲明。 – anatolyg

+1

是':: wizNtrKit'靜態對象嗎?它的聯繫是什麼? – Walter

+0

此外,功能在哪裏出現?頭文件,源文件?有多少個源文件包含它? –

回答

36

非靜態的inline函數聲明在每個使用它的翻譯單元(源文件)中引用相同的函數。

一個定義規則要求函數定義的主體在每個包含它的TU中都是相同的,並且具有「相同」的長期定義。如果源文件全部使用相同的頭文件,並且該函數不使用具有內部鏈接的任何全局名稱(包括static函數)或在不同TU中定義不同的宏,則通常可以滿足此要求。

我不記得之前遇到特定的鏈接器錯誤,但它至少有可能是這些限制之一負責。滿足這些要求是您的責任:未定義的行爲,如果您不需要,則不需要診斷。

static inline函數聲明指的是每個翻譯單元中的一個不同的函數,只是碰巧具有相同的名稱。它可以使用static全局名稱或在不同TU中有所不同的宏,在這種情況下,即使函數在頭文件中的定義「看起來相同」,函數在不同的TU中的行爲可能會有所不同。

由於這種差異,如果函數包含任何static局部變量,那麼它的行爲將根據是否爲static而有所不同。如果它是static,那麼每個TU都有自己的函數版本,因此它有自己的static局部變量副本。如果僅爲inline,則所有TU使用的局部變量只有一個拷貝static

+2

注意:對於'static'函數,'inline'位失去其語義(*沒關係,如果該函數定義出現在多個TU *)中;唯一依附於'inline'的東西只是編譯器的一個暗示,幾乎可以忽略。 –

+0

是的,除了「一個定義規則」要求外,我對「內聯」函數的說法也適用於既不是「靜態」也不是「內聯」的函數聲明。不需要在每個TU中定義相同的定義,只需要一個TU就可以包含定義。鑑於提問者的代碼在「內聯」被刪除時起作用,我懷疑這裏發生了一些有趣的事情 - 如果在多個TU中定義了鏈接器錯誤,您會期待鏈接器錯誤。我不認爲需要診斷,但對連接器來說並不困難。 –