編譯—連結—載入工具鏈

前置處理器(preprocessor)

/ PREE-pro-seh-sor /

在真正的編譯器看到你的程式碼之前,會先跑一個較簡單的程式,對它做純粹的文字手術。這個程式就是前置處理器。它完全不懂 C:它不知道 int 是什麼,也不知道函式在做什麼。它只懂得依照你寫在以 # 符號開頭的那幾行上的少數命令,去尋找、複製並貼上文字。

它的三大工作是:文字引入(當它看到 #include <stdio.h>,會找到那個標頭檔並把它的全部內容貼進來,彷彿是你親手打的)、文字替換(當你寫 #define PI 3.14159,它會把後面每一個 PI 這個字替換成 3.14159),以及條件引入(用 #ifdef 之類的指令,依某個名稱是否已定義,決定保留或丟棄整段文字)。輸出是一大塊純文字,所有 # 行都不見了、所有貼上都完成了。那份輸出才是編譯器本體真正讀的東西。

正因為它是盲目的文字替換,前置處理器既強大又危險。它會欣然產生看似正確卻實則不對的程式碼,因為它忽略了編譯器會強制執行的所有意義規則。這就是為什麼老練的 C 與 C++ 程式設計師會謹慎使用它,能用真正的語言特性(如 const 變數與 inline 函式)時就用,只把前置處理器留給少數只有它能做的工作,例如引入標頭檔與防止重複引入。

#define SQUARE(x) ((x)*(x)) // 前置處理器把: y = SQUARE(3); // 變成純文字: y = ((3)*(3)); // 在編譯器看到之前

替換是文字性的:編譯器只會看到右邊的結果,而非巨集的名稱。

前置處理器完全不懂 C 的型別、範圍或語意;它可能產生在某些方面有誤的文字,編譯器接著會以指向展開後程式碼的令人困惑訊息抱怨。

又稱
C preprocessorcpp前置處理器