2013-06-25 88 views
2

在下列情況下,編譯器是否允許優化掉foo()和/或整個if塊的調用?C/C++允許短循環編譯器優化

if(foo() && 0) 
    { ... } 
+0

編譯器被允許執行任何能夠產生C標準定義的正確結果的東西...所以foo()是否可以優化取決於它的功能,當然它可以優化if塊因爲它永遠不會被執行。 –

回答

14

從標準點的視圖,編譯器必須評估左手側,即foo()必須被調用:

[C99,6.5.13]不同於按位二進制&運營商,&&運營商保證從左到右的評估; 評估第一個操作數後有一個序列點。如果第一個操作數 的值等於0,則不計算第二個操作數。

但由於它知道if語句的身體永遠不能達到,*那麼它是免費的,省略任何相應的代碼部分。

當然,如果編譯器可以證明foo()沒有可觀察到的副作用,那麼它也可以自由優化該呼叫。但這與短路行爲無關。


*(C++ - 只)假設foo()不與operator&&過載返回類型。

+0

+1。我認爲\ _ \ _屬性\ _ \ _((純))在這裏值得一提。 – Elazar

+0

@Elazar:考慮到'foo()'沒有參數,純函數完全依賴於它們的參數,'foo()'實際上必須返回一個常量。然後'constexpr'是更好的解決方案。 – MSalters

1

等效代碼:

int x = (int) foo(); 
if (x) 
    if (0) 
     { ... } 

可以爲您 「優化掉」 的第一線,對於任意FOO? foo可能類似於

int foo() { 
    printf("x"); 
    return 0; 
} 
+0

是的,如果foo被定義爲像'int foo(){return 0; }如果是「 – Spook

+0

」。如果你有完整的知識,你總是可以優化一切。這與短時間無關。 – Elazar

2

編譯器有確定0意味着不執行在if聲明之前執行foo。但是,如果foo是一個非常簡單的函數,它沒有副作用(不會改變任何全局狀態 - 並且在C和C++標準中有很長的定義),那麼它本身可以被優化。通常只有在foo是相同源代碼的一部分時纔會發生。