C89(C90)、C99、C11——C語言的三套標準

2020-07-16 10:04:20
C語言最初由 Dennis Ritchie 於 1969 年到 1973 年在 AT&T 貝爾實驗室裡開發出來,主要用於重新實現 Unix 作業系統。此時,C語言又被稱為 K&R C。其中,K 表示 Kernighan 的首字母,而 R 則是 Ritchie 的首字母。

K&R C語言與後來標準化的C語言有很大差異,比如:
  • 如果函數返回型別為 int,則 int 可省:

    int my_function(){ }

    也可以寫成

    my_function(){ }

    編譯器不會有任何警告,更不會報錯。
  • 還有現在看來比較奇葩的函數定義,像我們現在定義這麼一個函數:

    void my_function(int a, char*p) {}

    如果是用 K&R C 語法定義的話要寫成:

    void my_function(a,p)int a; char*p; {}

    K&R 的C語法中,定義一個函數時,其形參列表先列出形參的識別符號,然後在函數宣告的後面緊跟著對形參識別符號的完整宣告,最後是函數體。這在現行標準中已經被逐步廢棄使用了。

另外,當時的第一本C語言專業書《The C Programming Language》也並非一個正式的程式語言規範,但被用了許多年。

C90 標準

由於C語言被各大公司所使用(包括當時處於鼎盛時期的 IBM PC),因此到了 1989 年,C語言由美國國家標準協會(ANSI)進行了標準化,此時C語言又被稱為 ANSI C。

而僅過一年,ANSI C 就被國際標準化組織 ISO 給採納了。此時,C語言在 ISO 中有了一個官方名稱——ISO/IEC 9899: 1990。其中:
  • 9899 是C語言在 ISO 標準中的代號,像 C++ 在 ISO 標準中的代號是 14882;
  • 而冒號後面的 1990 表示當前修訂好的版本是在 1990 年發布的。

對 於ISO/IEC 9899: 1990 的俗稱或簡稱,有些地方稱為 C89,有些地方稱為 C90,或者 C89/90。不管怎麼稱呼,它們都指代這個最初的C語言國際標準。

這個版本的C語言標準作為 K&R C 的一個超集(即 K&R C 是此標準C的一個子集),把後來引入的許多非官方特性也一起整合了進去。其中包括了從 C++ 借鑑的函數原型(Function Prototypes),指向 void 的指標,對國際字元集以及本地語言環境的支援。在此標準中,儘管已經將函數定義的方式改為現在我們常用的那種方式,不過K&R的語法形式仍然相容。

C99標準

在隨後的幾年裡,C語言的標準化委員會又不斷地對C語言進行改進,到了 1999 年,正式發布了 ISO/IEC 9899: 1999,簡稱為 C99 標準。

C99 標準引入了許多特性,包括行內函式(inline functions)、可變長度的陣列、靈活的陣列成員(用於結構體)、複合字面量、指定成員的初始化器、對IEEE754浮點數的改進、支援不定引數個數的宏定義,在資料型別上還增加了 long long int 以及複數型別。

毫不誇張地說,即便到目前為止,很少有C語言編譯器是完整支援 C99 的。像主流的 GCC 以及 Clang 編譯器都能支援高達90%以上,而微軟的 Visual Studio 2015 中的C編譯器只能支援到 70% 左右。

C11標準

2007 年,C語言標準委員會又重新開始修訂C語言,到了 2011 年正式發布了 ISO/IEC 9899: 2011,簡稱為 C11 標準。

C11標準新引入的特徵儘管沒 C99 相對 C90 引入的那麼多,但是這些也都十分有用,比如:位元組對齊說明符、泛型機制(generic selection)、對多執行緒的支援、靜態斷言、原子操作以及對 Unicode 的支援。

關於C語言歷史與演化進程的詳細介紹可參考維基百科:https://en.wikipedia.org/wiki/C_%28programming_language。

筆者近兩年也是在不斷地了解C語言標準委員會的最新動態(可參見:http://www.open-std.org/jtc1/sc22/wg14/),其中看到有人提出想為C語言新增物件導向的特性,包括增加類、繼承、多型等已被 C++ 語言所廣泛使用的語法特性,但是最終被委員會駁回了。因為這些複雜的語法特性並不符合C語言的設計理念以及設計哲學,況且 C++ 已經有了這些特性,C語言無需再對它們進行支援。