最佳化器對堆疊記憶體分配的看法
在 C 領域,問題出現了:編譯器可以最佳化堆記憶體分配嗎?讓我們深入研究這個有趣的主題。
考慮以下程式碼片段:
int main() { int* mem = new int[100]; return 0; }
編譯器是否有權利刪除新呼叫?根據我們的研究,g 和 Visual Studio 迴避這種最佳化,而 clang 則擁抱它。這種差異引出了一個問題:new 是否依賴底層系統調用,導致編譯器最佳化不切實際且不允許?
編譯器的理由
為了澄清這個難題,我們必須承認 N3664 的作用,該提案允許編譯器圍繞記憶體分配進行最佳化。然而,這種優化是在 N3664 之前構思的,引發了對其有效性的質疑。
為了回答這個問題,我們轉向「as-if」規則,這是 C 標準的一個基本面向。該規則允許實現偏離特定要求,只要它們保持程序的可觀察行為即可。
由於 new 可能會引發異常,從而改變程式的回傳值,因此「as-if」規則似乎禁止它的最佳化。然而,編譯器可能認為異常處理是實作細節,在這種情況下,不會觸發異常。因此,消除 new 呼叫不會違反“as-if”規則。
此外,「as-if」規則擴展到 new 的非拋出版本。然而,在單獨的翻譯單元中存在新的替代運算子可能會影響可觀察的行為。因此,編譯器必須確保不存在這種情況才能安全地執行此最佳化。
Clang 的激進方法
以前的 clang 版本即使在這種情況下也進行了優化,但後來版本變得更加謹慎。
總之,編譯器可以利用最佳化堆記憶體分配,包括使用 new 進行的分配。然而,這種優化必須遵守「as-if」規則的細微差別以及 C 異常處理機制的複雜性。
以上是C 編譯器可以最佳化堆記憶體分配嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!