2
A
回答
3
典型地,產生經預處理的翻譯單元預處理器運行之後和(粘貼在#include
地方整個頭文件,#define
的取代所有的地方,的#ifdef
條件句完全除去等無活性的分支),編譯器運行。大多數現代編譯器通常也能夠自己進行預處理,但由於歷史原因,C預處理器(cpp
)和C編譯器(cc
)至少在概念上是不同的。前者的輸出作爲後者的輸入。
在後續階段,完全取決於編譯器的內部實現,這些階段是什麼以及它們的順序是什麼。然而,最「傳統」的管道是:
- Lexing:令牌相互分離;
- 解析:根據語言語法解釋標記的組合並生成解析樹;
- 生成抽象語法樹:將分析樹作爲輸入並生成更好用,更好的註釋樹;
- 範圍分析:將使用的標識符與它們各自的聲明進行匹配,在未聲明標識符的情況下發出錯誤;
- 類型檢查:檢查每個表達式的類型是否與特定上下文中的預期類型匹配。在這個階段過去之後,沒有發生任何錯誤,程序在語法和語義上都被認爲是正確的,所以我們可以繼續下一步;
- 代碼生成和優化:可能在此階段,編譯器會發出,例如
4
來代替代表sizeof(int)
的抽象節點。它還會將3 + 4
等常量表達式嚼碎成7
。
注意sizeof
可以在運行時的情況下被評估它被施加到一個可變長度數組(C99起):
int n;
n = ...;
int vl_arr[n];
sizeof(vl_arr); // could be evaluated at runtime if "n" is not known at compile-time
相關問題
- 1. 編譯器如何工作以評估sizeof運算符在c
- 2. 調試標誌和GCC(編譯階段/鏈接階段)
- 3. 對象評估時調用哪個運算符?
- 4. sizeof運算符編譯時或運行時間
- 5. gof對VLA的sizeof運算符進行了不同的評估嗎?
- 6. 編譯/運行時Java枚舉評估
- 7. ostream C++運算符的懶惰評估
- 8. C中的評估&&運算符
- 9. 比較運算符的評估順序?
- 10. 範圍解析運算符的評估
- 11. 編譯器能否跳過對逗號運算符左操作數的評估?
- 12. 運算符重載編譯在Visual Studio 2013而不是gcc的
- 13. 評估順序和運算符<<
- 14. 如何評估SQL OR運算符
- 15. 後綴增量運算符評估
- 16. sizeof運算符的問題
- 17. Sizeof運算符實現:它如何在編譯時計算大小?
- 18. 編譯器評估顯式空檢查與空合併運算符?
- 19. 編譯時間評估
- 20. 運行(C#)算法評估
- 21. 評估包含在字符串中的運算符的操作
- 22. 編譯器的階段?
- 23. GWT中的算術運算評估
- 24. 基於sizeof運算符
- 25. 是在編譯時或運行時評估的F#範圍
- 26. 哪個運算符重載已用於ifstream對象以評估布爾值
- 27. Ruby - 如何評估兩個數字和一個運算符?
- 28. C代碼宏評估在編譯時
- 29. 力constexpr在編譯時進行評估
- 30. 評估和打印階乘
什麼都是「編譯」狀態? –
在預處理程序運行後(預處理程序不識別sizeof),在彙編程序創建目標文件或鏈接生成可執行文件之前對其進行評估 - 因此它在主「編譯器」中進行評估。請注意,預處理器,編譯器和彙編器(實際上是連接器)都可以是單個程序,也可以是多個程序;該標準不關心。 VLA的大小 - 可變長度數組是個例外。這可能需要在運行時而不是編譯時進行評估。 –
@JonathanLeffler你應該將其作爲答案發布。 – Lundin