6

比方說,我有一個簡單的功能是這樣的:短路運營商和尾遞歸

int all_true(int* bools, int len) { 
    if (len < 1) return TRUE; 
    return *bools && all_true(bools+1, len-1); 
} 

該功能可以在一個更明顯的尾遞歸風格被改寫爲:

int all_true(int* bools, int len) { 
    if (len < 1) return TRUE; 
    if (!*bools) return FALSE; 
    return all_true(bools+1, len-1); 
} 

從邏輯上講,兩者之間沒有差別;假設bools僅包含TRUEFALSE(明智地定義),它們完全相同。

我的問題是:如果一個編譯器足夠聰明,可以優化秒作爲尾遞歸調用,是否有理由期望它以相同的方式優化第一個,因爲「& &」短路?顯然,如果使用非短路運算符,這將是尾遞歸,因爲在運算符被應用之前,兩個表達式都將被求值,但我對短路情況感到好奇。 (在我收到大量評論之前告訴我C編譯器通常不會優化尾遞歸調用:認爲這是一個關於使用短語運算符來優化尾遞歸調用的常見問題,與語言無關。我很樂意在Scheme,Haskell,OCaml,F#,Python或者其他什麼東西中重寫這個,如果你不明白C的話。)

+0

gcc確實優化了遞歸調用。 – Arafangion 2011-12-15 04:57:14

回答

2

你的問題真的是「編譯器有多聰明?」但是你沒有說明你正在使用哪個編譯器。

給定一個假設的合理編譯器,在優化之前將源代碼轉換爲中間流程圖,您編寫的代碼片段可以用相同的方式表示(操作符儘管方便鍵入)並不近因爲它被編譯爲&運算符;所以如果它在假設編譯器的一個階段被擴展出來,我不會感到驚訝)。根據這個假設,有理由斷言你的問題的答案是「是」。然而,如果你真的要依賴這個,你應該用你正在使用的任何編譯器來測試它。