2016-09-14 38 views
2

sizeof是編譯時運算符。 See heresizeof運算符評估在gcc編譯的哪個階段

編譯有很多階段。 sizeof運營商在哪個階段評估?

+0

什麼都是「編譯」狀態? –

+3

在預處理程序運行後(預處理程序不識別sizeof),在彙編程序創建目標文件或鏈接生成可執行文件之前對其進行評估 - 因此它在主「編譯器」中進行評估。請注意,預處理器,編譯器和彙編器(實際上是連接器)都可以是單個程序,也可以是多個程序;該標準不關心。 VLA的大小 - 可變長度數組是個例外。這可能需要在運行時而不是編譯時進行評估。 –

+0

@JonathanLeffler你應該將其作爲答案發布。 – Lundin

回答

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