2011-11-06 64 views
0
const int thing = 1234; 

int func(int hello) 
{ 
    return hello/(thing*123+321); 
} 

(thing*123+321)在編譯時計算的?使用靜態/全局const原語進行計算是否在編譯時發生?

如果thing是一個用戶定義的類型int operator*它也會發生在編譯時?

如果thing是一個浮點數或雙精度浮點數也會在編譯時發生嗎?

如果我在運行時強制更改thing(thing*123+321)保持不變?

+0

您可以自己獲得答案如果你看看生成的代碼! – hansmaad

+1

@hansmaad我需要知道更多的答案,而不是我的特定編譯器碰巧做的。 – David

+0

生成的代碼是二進制(或組件,如果一個指定適當的編譯器選項)。它不會幫助不懂彙編語言的人。 – cHao

回答

3

這並不能保證,但任何優化的編譯器都會預先計算這個值。它可能會把這種劃分操作變成一個乘以預先計算的倒數值的乘法運算。

+0

我相信只有在指定相當於'-fast-math'(在GCC中)的選項時纔可以使用互惠值,因爲此代碼可能會產生與乘法有細微差別的結果。 –

+0

@KonradRudolph:*整數*數學? –

+0

@David Duh。對。 –

0

是在編譯時計算的(thing * 123 + 321)嗎?

是的。

hello /(thing * 123 + 321);

在這種情況下,完整表達式是在運行時計算的。因爲函數hello中的參數在運行程序之前是未知的。

+0

該表達式中未使用該參數。沒有任何東西(除了浮點精度的規則,但在這種情況下,甚至沒有),禁止編譯器在編譯時計算子表達式。 –

+0

'thing * 123 + 321'部分*可以在編譯時計算出來,因爲它的所有值都是已知的。 – cHao

+0

這裏的措辭有點誤導。 「完整表達式」是一個特定的C++術語(§1.9/ 10),指的是不是子表達式的表達式。在這種情況下,完整表達式是一個分割表達式,事實上分割表達式是在運行時計算的。 – MSalters

1

一般來說,常量表達式可以並且通常會在編譯時計算。既然你可以,並且如果你確實使用常量表達式作爲模板參數,那實際上沒有辦法。

現在最大的問題是什麼構成了一個常量表達式。在C++ 98/03中,你的thing將被限定爲一個,但是一個不變的函數thing不會,因爲在這個意義上沒有辦法告訴編譯器函數是「純」的。

一些編譯器提供的擴展名(如GCC的屬性「純粹」和「常量」),但是這就是語言的範圍之內。 C++ 11引入了明確的constexpr關鍵字,該關鍵字允許您將各種表達式聲明爲常量,從而有資格進行編譯時評估。 (例如,GCC使用GMP和MPFR庫構建,以便以任何精度執行編譯時計算,以便能夠定位到任何平臺。)

相關問題