我已經看到,使用優化級別3的GCC編譯器內聯靜態函數,但在一種情況下不內聯非靜態函數。而在其他情況下,它將函數內聯,而不管是靜態的還是非靜態的。 我想知道哪些參數會選擇靜態或非靜態函數進行內聯。C編譯器優化(gcc):自動內聯非靜態函數vs靜態函數
回答
從GCC手冊:
-O3執行最多的優化。 -O3打開由-O2指定的所有優化,並打開-finline函數, -funswitch-loops,-fpredictive-commoning,-fgcse-after-reload,-ftree-loop-vectorize,-ftree-loop- distribution-patterns, -fsplit-paths -ftree-slp-vectorize,-fvect-cost-model,-ftree-partial-pre和-fipa-cp -clone選項。
好像你的話來自-finline-功能選項:
-finline函數
考慮所有功能內聯,即使他們不聲明爲inline。編譯器試探性地決定哪些功能值得以這種方式進行集成。
如果對給定函數的所有調用都被集成,並且該函數被聲明爲「靜態」,那麼函數通常不會輸出爲彙編代碼本身。
在-O3級別啓用。
其實所有的功能都受到在-O3優化模式由GCC被內聯,無論是聯聲明,靜態的,沒有或兩者兼而有之。
這裏的gcc的手冊頁(-Winline選項)的另一大塊:
編譯器使用各種啓發式,以確定是否要內聯函數。例如,編譯器 考慮了內聯函數的大小以及當前函數中已經完成的內聯量。
因此,gcc使用函數的大小和函數中的內聯函數來選擇內聯還是不內聯。如果你想知道更多關於這些啓發式的知識,恐怕你可能需要查看gcc的源代碼:)
這裏的重要啓發是「靜態」單一調用函數,並且通過所有體面的優化C編譯器。內聯實際上是一種尺寸與速度的折衷方案,但如果實際上沒有任何東西丟失,因爲非內聯版本無法訪問可能會被丟棄。自然有皺紋和特殊情況,但這是一般的想法。 – doynax
- 1. 如何使用非靜態函數內部靜態函數
- 2. 靜態函數調用非靜態函數在C++
- 3. 工廠方法:靜態函數VS C++中的非靜態函數實現
- 4. 靜態模板函數可以通過編譯器內聯嗎?
- 5. C靜態內聯函數調用外部函數動機
- 6. 靜態函數和非靜態變量
- 7. 靜態函數靜態函數
- 8. 錯誤由於早期非靜態非內聯函數的靜態線版本
- 9. gcc靜態鏈接程序能否從靜態庫中正確內聯函數?
- 10. 從靜態函數調用非靜態函數
- 11. 靜態函數VS const函數
- 12. 非靜態成員函數
- 13. 內聯函數和靜態內聯函數之間的區別
- 14. 內聯函數調用靜態內聯函數
- 15. 類中的靜態內聯函數
- 16. 靜態內聯函數的標識?
- 17. 調用靜態內聯函數
- 18. libc中的靜態內聯函數
- 19. 靜態函數,內聯和模板?
- 20. 比較非靜態函數中的靜態和非靜態整數
- 21. 靜態局部變量C99靜態內聯函數
- 22. 內聯靜態函數和靜態變量
- 23. 編譯器會優化靜態函數的未使用參數嗎?
- 24. 靜態線程函數訪問非靜態類成員在C++
- 25. 在C++中更新靜態函數中的非靜態成員
- 26. 靜態函數
- 27. 靜態函數
- 28. C中的靜態函數和非靜態函數之間的差別
- 29. gcc無法編譯名稱空間中的靜態函數
- 30. C「靜態」優化
我很肯定你沒有在GCC的源代碼之外找到完整的列表。當然,這可以因編譯器和編譯器的不同而不同。但是,該標準包含一些限制。 –
如果因爲編譯器知道如何使用它的地址而永遠不會返回其地址,則可以內聯一個靜態函數。非靜態函數不一定是內聯的,因爲其他源文件中的代碼可能會調用它。或者,至少必須定義非內聯函數,以便可以從其他翻譯單元調用它,即使本地使用是內聯的。 –