2011-01-24 63 views
7

我想盡可能用C編寫一個功能風格的程序。 我知道像GCC/Clang這樣的精細編譯器會默默地調用尾部優化,但不能保證。是否有任何選項可以強制編譯器調用尾部調用? (當然,當它只是在它自己的末尾被調用時)是否可以強制執行GCC/Clang上的尾部呼叫優化?

+4

編譯器在這方面可能相當聰明,只要相信它。不需要*不便攜*黑客。 – 2011-01-24 17:38:43

+1

在你認爲尾部優化應該發生但編譯器無法做到的情況下(無論出於何種原因),你希望發生什麼? – 2011-01-24 18:40:52

回答

4

鏗鏘根本沒有做任何優化。有一個LLVM傳球tailcallelim它可以做你想做的事情(但不能保證)。您可以使用opt單獨運行。

0

實際上很多C的編譯器已經爲你處理了這個問題。正如上面提到的那樣,你不妨讓編譯器處理大部分這些事情,而不是試圖創建在其他地方不起作用的優化。通常情況下,即使您設置了優化標誌,實際上沒有性能差異,您仍會發現。

1

薈萃答案:

有一些教訓,這是接管成函數式語言Ç有用:使用不發生變異無論是全局或輸入參數的小功能,使用功能,不要害怕函數指針。但是在這裏你可以合理地做到這一點,並且依靠尾部呼叫消除('tail-call optimization'並不是真的是正確的術語)可能超出了有用的範圍。你不能強迫編譯器使用這種策略,即使你可以,最終的C也會非常單一,並且很難爲其他人閱讀,包括你未來的自我。

使用語言來發揮自己的優勢。 C 對某些事物有好處,所以用它來表達C語言風格。如果你想要不同的優勢,或者如果你想使用功能性風格(出色的決策!),請使用功能性語言。

0

如果它確實是一個尾部呼叫,那麼while循環或goto不會看起來與遞歸調用有很大不同。只需更新所有變量,而不是將它們作爲參數傳遞。 AFAIK這是C中唯一的跨平臺方式來控制所有優化級別的堆棧使用情況。它實際上可以更具可讀性,因爲你有一個初始化函數,接着是循環,這非常習慣。尾遞歸版本需要兩個函數,一個用於初始化,一個用於遞歸部分。

相關問題