跳轉到

2018:C17 小修訂——穩定優先的時代#

事件#

2018 年,ISO 發佈 ISO/IEC 9899:2018(C17,又稱 C18)。這是一個「不新增任何特性」的修訂,只解決 C11 的缺陷報告(defect reports)與小問題,並把若干實作爭議明確化。

為何重要#

  • 新語法:無。C17 的重點恰恰是「不加東西」——委員會體認到 C11 的許多新特性(Annex K 邊界檢查、threads.h)在業界幾乎沒有採用,先穩定再擴充。
  • C 標準化節奏的改變:與 C99/C11 的大躍進相比,C17 反映了「C 語言已經夠用,缺陷比特性更重要」的態度。

理論與實用原因#

  • 理論原因:語言標準的價值在於一致性與可預測性;C11 中過多「選用特性」(VLA、Annex K、threads.h)讓「什麼是 C」變得模糊,C17 收斂這些分歧。
  • 實用原因:業界(Linux、glibc、各大編譯器)拒絕實作 Annex K,證明「委員會設計的安全介面」不敵「社群實作的工具」(ASan、靜態分析)——這個教訓影響了 C23 的設計方向:安全靠工具與模式而非語法堆疊。

彌補了什麼缺陷#

彌補了 C11「特性過多、選用機制過濫、實作分歧、缺陷報告未消化」的缺陷。C17 的意義在於承認:C 語言的未來不在加語法,而在穩定語意與支援工具化安全。

程式範例#

C17 沒有新語法,但以下例子說明它「收斂分歧」的意義——檢測各選用特性:

/* C11 留下的「什麼是 C」分歧,用編譯器內建巨集偵測 */
#include <stdio.h>

int main(void) {
    printf("標準版本: %ld\n", (long)__STDC_VERSION__);
    /* C89 無此巨集;C95=199409L; C99=199901L; C11/C17=201112L/201710L */
#ifdef __STDC_NO_VLA__
    printf("不支援 VLA\n");       /* C11 起可偵測 */
#endif
#ifdef __STDC_NO_THREADS__
    printf("不支援 threads.h\n"); /* 嵌入式編譯器常省略 */
#endif
    return 0;
}
$ gcc -std=c11 detect.c && ./a.out
標準版本: 201112
$ gcc -std=c17 detect.c && ./a.out
標準版本: 201710

C17 的教訓——「委員會設計的安全介面」不敵「社群實作的工具」:

/* C11 Annex K 邊界檢查介面(委員會設計,業界幾乎無人採用) */
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>

char buf[8];
strcpy_s(buf, sizeof buf, "hello");   /* 語法繁瑣、glibc/GCC 拒絕實作 */

/* 業界實際採用的路線:工具 + 簡單寫法 */
snprintf(buf, sizeof buf, "%s", "hello");     /* C99,早已通用 */
/* 或 gcc -fsanitize=address —— 編譯期零改動,執行期自動抓錯 */

相關條目#