2009-07-30 94 views
9

我知道你可以使用inline關鍵字,或者只是在類聲明ala short ctor或getter方法中放置一個方法,但是編譯器會在什麼時候內聯我的方法做出最終決定?編譯器是否決定何時內聯函數(使用C++)?

例如:

inline void Foo::vLongBar() 
{ 
    //several function calls and lines of code 
} 

將編譯器忽略,如果它認爲它會讓我的代碼效率低下我的inline聲明?

作爲一個方面的問題,如果我宣佈我的課之外的getter方法是這樣的:

void Foo::bar() { std::cout << "baz"; } 

請問在幕後編譯器內聯呢?

回答

9

無論是否fiunction是內聯就是,在一天結束的時候,完全編譯器最多可達 。通常,函數在流程方面越複雜,編譯器將其內聯的可能性就越小。並且一些函數(如遞歸函數)不能被內聯。

不內聯函數的主要原因是它會大大增加代碼的總體大小,防止Iot被保存在處理器的緩存中。這實際上是一種悲觀,而不是一種優化。對於讓程序員決定自己在腳下或其他地方自己拍攝,你可以自己內聯函數 - 編寫在本函數的調用位置處已經進入函數的代碼。

+0

請看我對JaredPar的回答的評論。 – jkeys 2009-07-30 07:32:11

15

是的,內聯代碼的最終決定在於C++編譯器。 inline關鍵字是一個建議,而不是要求。

這裏有一些細節,如何這決定在Microsoft C++處理編譯

+1

你能詳細說明這是爲什麼嗎?我認爲C++的意義在於給程序員足夠的繩索來掛斷自己,但這似乎是限制性的。有沒有很好的理由? – jkeys 2009-07-30 07:31:27

+1

@Hooked,看看我發佈的鏈接。它詳細介紹了爲什麼這不總是一件好事。我想到的第一件事是頭遞歸函數。 – JaredPar 2009-07-30 07:32:13

+1

該標準規定,即使__forceinline沒有結束辯論,編譯器仍然有最後一句話。我可以理解什麼時候內聯會是不合適的,但是如果一個程序員/分析人員決定超編譯器,他有什麼選擇?該鏈接沒有詳細說明讓編譯器決定的理由。 – jkeys 2009-07-30 07:37:00

1

據我所知,編譯器會自動生成一個函數,如果它發現了一個類似for的循環,它會自動生成一個內聯函數(或者在類聲明中寫入)的非內聯函數。 這是編譯器最後一個例子在內聯函數中說。

4

正如許多已經公佈,最終決定始終是編譯器,即使你可以給公司的提示,如forceinline。
基本原理的一部分是內聯不是一個自動「更快」的開關。內聯過多會使您的代碼變得更大,並且可能會干擾其他優化。見The C++ FAQ Lite about inline functions and performance

2

作爲一個方面的問題,如果我宣佈一個getter方法我班外面是這樣的:

void Foo::bar() { std::cout << "baz"; } 

請問在幕後編譯器內聯呢?

這取決於。它可以用於同一翻譯單元中的所有呼叫者(.cpp文件及其所有#included定義)。但它仍然需要編譯一個非內聯版本,因爲在翻譯單元之外可能會有該函數的調用者。您可以在高優化級別上看到這一點(如果您的編譯器實際上可以實現這一點)。 (尤其是:比較將#include所有.cpp文件中的所有.cpp文件與典型佈局進行比較。在一個翻譯單元中的所有定義都會顯着增加這種內聯的機會。)

3

正如其他人注意到的,inline關鍵字僅僅是對編譯器內聯代碼的一種建議。由於編譯器會經常內嵌沒有標記爲inline的代碼,而不是內聯代碼,所以關鍵字看起來與register或(pre-C++ 0x)auto一樣多餘。

然而,有一件事是,inline關鍵字效果:它改變了從外部(默認爲功能)功能的聯動在線。內聯鏈接允許每個編譯單元包含它自己的目標代碼副本,並且鏈接器從最終的可執行文件中刪除多餘的副本。如果這提醒你模板,是的,模板也使用內聯鏈接。

3

我想補充我5毛錢......

我發現這個Guru of Week文章關於內聯非常有用的。

據我所知,我在某處甚至連鏈接器都可能做內聯,當它鏈接對象文件並發現被鏈接的代碼可以內聯。

問候,
Ovanes

1

如果你真的肯定,絕對沒有失敗NEED內聯代碼,總有宏。 C多年來一直支持這些技術,並且因爲它們在編譯之前只是文本替換,所以它們確實真實地嵌入了您所寫的任何內容。

這就是爲什麼'inline'關鍵字(甚至在某些情況下是強制變體)可以承受沒有強制它的標準方式 - 你總是可以寫一個宏。

也就是說,inline關鍵字通常更好,因爲編譯器經常知道是否使內聯函數有意義,並且因爲內聯可以與編譯器優化的其餘部分進行交互。

相關問題