2011-08-18 124 views
21

使用新的C++ 11標準,我應該何時使用關鍵字constexpr關鍵字inlineconstexpr關鍵字是否提供了比inline更多的優化,還是僅僅聲稱必須在編譯時計算?inline vs. constexpr?

爲什麼constexpr在呼叫不固定的某些情況下在GCC上工作,例如在非constexpr變量上調用foo(x)?這是GCC中的錯誤還是它實際上是標準的一部分?

回答

26

斷言在編譯時可以計算出一些東西是一種非常強大的優化。

內聯只是通過將函數體複製/粘貼到調用站點來刪除函數調用。函數體仍然需要執行,你只需要保存函數調用的開銷。

但是,如果您在編譯時對相同的代碼進行評估,那麼在運行時它是免費

但是inlineconstexpr都不是主要是關於優化。 inline的主要目的是抑制一個定義規則,以便可以在頭文件中定義函數(這對模板有用,而且順便也使內聯優化更容易)

constexpr是因爲它在元編程中很有用,順便說一句,它可以幫助編譯器更好地優化代碼,將更多的計算轉移到編譯時。

+5

根據[這個問題](http://stackoverflow.com/q/7065200/636019),當'constexpr'函數沒有用在需要常量表達式的上下文中時,編譯器沒有義務計算表達式在編譯時。 – ildjarn

+0

但它仍指定計算*可以在編譯時執行。與'inline'一樣,它並不是真正的優化,但它可以提供編譯器可以用來優化的其他信息。 – jalf

+0

對,我只是在挑剔使用「must」這個詞。 : - ] – ildjarn

1

引述維基百科:

的C++ 0x將介紹關鍵字constexpr,其允許用戶 保證的功能或對象的構造是一個編譯時 常數。

標記函數內聯,如果他們超短。如果編譯時需要結果,則標記函數爲constexpr。 (模板參數或數組大小)。如果需要,我相信一個函數可以是兩個。

可以使用 非constexpr參數調用常量表達式函數或構造函數。正如一個constexpr整數文字可以被分配給一個非constexpr變量的 ,一個constexpr函數 也可以用非constexpr參數調用,並且結果存儲在 非constexpr變量中。當表達式的所有成員都是 constexpr時,關鍵字只允許編譯時恆定性的可能性 。

因此,海灣合作委員會在這不是不正確的。

-2

雖然inline對編譯器說「這個函數在這個翻譯單元的某個地方使用,並沒有公開給其他目標文件」,但編譯器很可能會將函數主體插入到調用者中。 constexpr函數對編譯器說:「這個函數沒有副作用,也不依賴於除參數本身之外的前提條件。「

constexpr變量只是說」這個變量不會改變,它的數據可以包含在代碼中「但是它會影響你在一個靜態或非靜態函數中定義一個constexpr變量,例如,如果一個constexpr陣列是非靜態,GCC只是使用硬編碼mov -instructions將數據移動到堆棧,而只是static constexpr存儲在.text -section的數據。

分配給一個變量Lambda表達式,而不捕獲可能比捕獲constexpr其他,因爲沒有他們不需要記憶來保存捕捉,並且他們的工作像一個空載的類,超載operator()(但它們甚至可以被轉換爲普通函數p帶有簡單的一元加號:+[]{})。

+0

'inline'並不意味着內部鏈接,因爲您似乎在第一段中說過 –