2016-02-25 73 views
0

我希望我的編譯器(VS 2013)避免任何冗餘的算術計算,最好是在編譯時計算一次。編譯器評估常量表達式

基本上我看到三種情況如下:

例如:

void Mesh::Draw1() 
{ 
    const static uint32_t gStaticOffset = 0; 
    const static uint32_t gVertexSize = sizeof(float) * 3; 
    const static uint32_t gBoneIndexSize = sizeof(uint32_t) * MAX_BONES; 
    const static uint32_t gBoneWeightSize = sizeof(float) * MAX_BONES; 

    ... 
} 

VS

void Mesh::Draw2() 
{ 
    const uint32_t staticOffset = 0; 
    const uint32_t vertexSize = sizeof(float) * 3; 
    const uint32_t boneIndexSize = sizeof(uint32_t) * MAX_BONES; 
    const uint32_t boneWeightSize = sizeof(float) * MAX_BONES; 

    ... 
} 

VS

const static uint32_t gStaticOffset = 0; 
const static uint32_t gVertexSize = sizeof(float) * 3; 
const static uint32_t gBoneIndexSize = sizeof(uint32_t) * MAX_BONES; 
const static uint32_t gBoneWeightSize = sizeof(float) * MAX_BONES; 

void Mesh::Draw3() 
{ 
    ... 
} 

我的想法,請糾正我,如果錯了:

  • Draw1()可能會重新計算本地的表達依賴於編譯器的每個函數調用
  • Draw2()Draw3()保證表達式僅計算一次, 如果不是在編譯時則在運行期間
  • 是否有任何表達式爲編譯時評估的三種變化將完全取決於編譯器

編譯器是否會爲每個代碼生成不同的代碼,如果是這樣,哪一個避免了最多餘的計算?

+0

我建議你看這個視頻:https://www.youtube.com/watch?v = FnGCDLhaxKU。 Chandler在那裏明確地提到了'const_cast',並且暗示瞭如何處理const - 也就是說,像數據流這樣的事情很難預測,所以最好簡單地測試它。 – atlaste

+1

@atl對不起,我不明白'const_cast'與什麼有關。如果我有時間觀看2小時的視頻,我想也許我會理解這種關係......也許你可以總結一下嗎? –

+1

另請參閱此處:http://goo.gl/GBcVKm –

回答

4

有沒有辦法是某些你的編譯器會做什麼,除非你嘗試它。編譯所有三個代碼示例,然後查看生成的目標代碼。

實際上,他們應該都是相同的。在編譯器優化方面,持續摺疊是低懸的最低水果。如果你的編譯器在編譯時沒有計算這些常量,那麼它是而不是的優化編譯器。除非你有一個很好的理由繼續使用它,否則你應該把它交給垃圾堆,並找到一個不同的垃圾堆。

+0

我甚至會用一組更強的單詞 - '如果你的編譯器不是在編譯時不計算這些常量,**把它扔掉**並使用另一個。 – SergeyA

+0

@sergey我原本是這樣寫的,但是認爲你可能使用了一種特殊的嵌入式編譯器,它絕對沒有任何優化。不過,在這種情況下,您必須檢查輸出以瞭解發生了什麼。 –