2012-11-23 47 views
3

只是一些opitmization考慮:英特爾C++編譯器是否優化了代碼中從未調用過的函數?

有誰知道它肯定是否英特爾C++編譯器(如ICC 13.0,而引起的,與像/ O3等一些optimzation選項編譯)會自動優化出所有不使用/多餘結構/類/功能/下面在像examplefun(代碼變量):

  //...defining examplefunc()....// 

     const int a=0; 
     if (a>0) 
      int b=examplefunc(); 

回答

4

編譯器通常不優化出未使用的函數,除非它們是static,因此,僅在特定的模塊內訪問。但是,如果鏈接在功能級而不是模塊級完成,鏈接器可能會死掉該功能。

您可以檢查裝配輸出,鏈接程序映射,或使用類似objdump檢查功能被列入鏈接的二進制文件。

3

我不認爲這個問題是正確的。雖然這個問題的字面意思是問編譯器是否會優化掉一個沒有使用的函數,但這是隻有鏈接器才能做到的。

那麼編譯器可以做什麼?編譯器可以優化掉死代碼,例如在上面的代碼中,因爲a已知爲0,編譯器可以完全刪除if語句。對於大多數用途來說,這足夠好了(無論函數是否執行到可執行文件都不會影響性能,分支是否被避免會影響函數的性能 - 特別是分支錯誤預測)。另外,如果編譯器優化了上面的分支,程序中會少一個引用exampleFunc函數,並且當鏈接器處理生成的二進制文件時,如果在整個程序中沒有對函數的引用,它可以完全放棄符號。請注意,這隻能作爲程序鏈接的一部分,對於庫,即使該函數現在不被調用,稍後與庫鏈接的程序也可能使用它。

所以回到原來的問題,編譯器會優化掉分支,並且鏈接器可能是或者不從二進制中移除函數,但那應該不重要。

關於其他構造,對於structclass,唯一使它成爲二進制的是成員函數,同樣的事情適用於那裏:如果你連接的程序並沒有使用任何函數,鏈接器可以刪除這些符號。

+0

呃,我覺得這個區別有點平庸。整個工具鏈是「編譯器」,它本身有一個「編譯器」和「鏈接器」(和「預處理器」等)。我們可以推斷上下文的含義。 – GManNickG

+0

@GManNickG:雖然我可以同意這兩個都是工具鏈的一部分,但如果你想通過檢查生成的對象來檢查它,那麼差異就很重要,函數將會在那裏(編譯器無法知道不同的TU是否使用它),但是並不意味着鏈接器不會刪除它。 –

+0

您正在回答您的問題(「編譯器」的定義)。英特爾編譯器包含了所有階段(「預處理器」,「編譯器」,「鏈接器」),我的意思是OP很可能意味着(也可能意味着,而且我會以同樣的方式寫作)。 「編譯器」這個詞被重載意味着多重的東西,但是你(不合理的,IMO)只是假設一個單一的定義,這會導致OP錯誤。如果你明白我的意思,我覺得它「不公平」。不要說你的定義是「錯誤的」,只是它不是唯一的定義。 – GManNickG

相關問題