基礎:機器模型

標準與規格(概覽)

誰決定一個 C 程式應該是什麼意思?不是任何單一的編譯器,也不是碰巧在維護某個編譯器的那個人。有一本寫下來的規則書——標準——精確地定義了這個語言,而每個打造編譯器的人都同意遵循它。規格(spec)就是那份大家認可、詳盡的描述,說明某樣東西必須如何運作,寫下來好讓彼此獨立的人能造出相容的零件。

就 C 而言,標準是由標準組織 ISO 與 IEC 發布的官方文件,歷年多次修訂(人們以 C89、C99、C11、C17、C23 這類版本稱呼)。它定義語法、每個語言構造的意義、標準函式庫必須提供什麼,以及——至關重要地——哪些東西是留作未定義或交由實作決定的。遵循它的編譯器稱為「符合標準的」。規格不是教學手冊;它是一份審慎的契約,寫成這樣,好讓依標準寫成的程式在任何符合標準的編譯器上行為一致,也讓工具製造者確切知道該造什麼。

為何重要:標準正是可攜程式碼之所以可能的原因——它是那份共同的協議,讓同一份原始碼能在不同編譯器與機器上一致地編譯與運作。它也是系統程式設計裡許多最鋒利概念被精確定義之處:尤其,標準正是宣告某些誤用為「未定義行為」的地方,意思是它對接下來會發生什麼完全不加要求。當你想知道某件事是被保證的、還是只是碰巧在你今天的編譯器上能動,最終的權威是標準——而不是編譯器的輸出。

你可以要求編譯器按某個特定標準來約束你:gcc -std=c11 -pedantic main.c 叫 gcc 遵循 C11,並對任何標準之外的東西發出警告。規格也定下 int 至少 16 位元(而非剛好 32),這正是為什麼可攜程式碼不去假設某個寬度。

標準是那份契約;-std= 告訴編譯器要強制執行哪個版本。

「符合標準」與「在我編譯器上能動」不是同一回事。倚賴未定義行為的程式碼今天也許跑得好好的,編譯器升級後卻壞掉,因為標準從未承諾任何事——編譯器本來就可以變。定義什麼是被保證的,是規格,而不是你上一次成功的執行。

又稱
language standardspecificationspecC standardISO C語言標準規範