一、C语言版本历史(不含gnu扩展)
早期发展
K&R C(1978)
- Brian Kernighan 与 Dennis Ritchie 出版《The C Programming Language》
- 非正式标准,也称"Classic C"
- 奠定了 C 语言的基础语法
标准版本
| 版本 | 年份 | 关键特性 |
|---|---|---|
| C89 / ANSI C | 1989 | 第一个官方标准(ANSI X3.159-1989),函数原型、void、const、volatile |
| C90 | 1990 | ISO 采纳 C89,内容基本相同(ISO/IEC 9899:1990) |
| C95 | 1995 | 小修订,增加宽字符支持(wchar_t)、二合字母 |
| C99 | 1999 | 行内函数 inline、变长数组(VLA)、// 注释、stdint.h、复数类型、restrict |
| C11 | 2011 | 多线程(<threads.h>)、原子操作、泛型宏 _Generic、匿名结构体/联合体、边界检查 |
| C17 / C18 | 2018 | 缺陷修复版,无新特性,澄清 C11 中的歧义 |
| C23 | 2024 | nullptr、bool/true/false 关键字、二进制字面量(0b1010)、typeof、属性语法 [[]] |
各版本亮点对比
K&R → C89 → C99 → C11 → C17 → C23
| | | | | |
基础 标准化 现代化 并发 修复 现代语法
重要里程碑说明
- C99 是目前嵌入式领域最广泛使用的版本
- C11 引入了真正的多线程标准支持
- C23 大幅向现代语言看齐,语法更简洁
- GCC、Clang、MSVC 对各标准的支持程度不同,编译时用
-std=c99、-std=c11等指定版本
注意事项:
二、包含gnu扩展的历史版本
C语言版本历史(含 GNU 扩展)
标准版本 + GNU 扩展
| 版本 | 年份 | 类型 | 关键特性 |
|---|---|---|---|
| K&R C | 1978 | 非正式 | 《The C Programming Language》奠基,Classic C |
| C89 / ANSI C | 1989 | ISO 标准 | 第一个官方标准,函数原型、void、const、volatile |
| C90 | 1990 | ISO 标准 | ISO 采纳 C89,内容基本相同(ISO/IEC 9899:1990) |
| GNU89 / gnu89 | 1989+ | GNU 扩展 | C89 + GCC 专属扩展(见下方详述) |
| C95 | 1995 | ISO 标准 | 增加宽字符 wchar_t、二合字母 |
| C99 | 1999 | ISO 标准 | inline、VLA、// 注释、stdint.h、复数类型、restrict |
| GNU99 / gnu99 | 1999+ | GNU 扩展 | C99 + GCC 专属扩展 |
| C11 | 2011 | ISO 标准 | 多线程 <threads.h>、原子操作、_Generic、匿名结构体 |
| GNU11 / gnu11 | 2011+ | GNU 扩展 | C11 + GCC 专属扩展(GCC 5 前的默认模式) |
| C17 / C18 | 2018 | ISO 标准 | 缺陷修复,无新特性 |
| GNU17 / gnu17 | 2018+ | GNU 扩展 | C17 + GCC 专属扩展(GCC 5+ 当前默认) |
| C23 | 2024 | ISO 标准 | nullptr、bool 关键字、二进制字面量、typeof、[[]] 属性 |
| GNU23 / gnu23 | 2024+ | GNU 扩展 | C23 + GCC 专属扩展 |
gnu89 专属扩展详解
gnu89 是 GCC 历史上最经典的扩展模式,曾长期作为 GCC 默认标准,Linux 内核早期即以此编写。
语法扩展
c
// 1. 语句表达式(Statement Expressions)
int result = ({ int x = 10; x * x; }); // 块可作为表达式
// 2. 嵌套函数(Nested Functions)
void outer() {
int inner(int x) { return x + 1; } // 函数内定义函数
printf("%d", inner(5));
}
// 3. 零长度数组(Flexible Array,比 C99 更早)
struct Packet {
int len;
char data[0]; // GNU 风格柔性数组
};
// 4. __typeof__ 运算符
__typeof__(x) y = x; // 类似 C23 的 typeof
// 5. 可变参数宏(C99 前的写法)
#define LOG(fmt, args...) printf(fmt, ##args)
内建函数与属性
c
// __attribute__ 扩展
void die() __attribute__((noreturn));
int add(int a, int b) __attribute__((pure));
// 内建函数
__builtin_expect(x == 0, 0); // 分支预测提示
__builtin_offsetof(struct, member);
GNU 扩展与标准的关系
ISO 标准 GNU 扩展(= 标准 + GCC 私有特性)
───────────── ──────────────────────────────────
C89 ──────→ gnu89 ← Linux 内核早期默认
C99 ──────→ gnu99
C11 ──────→ gnu11 ← GCC 4.x 默认
C17 ──────→ gnu17 ← GCC 5+ 当前默认
C23 ──────→ gnu23
编译器指定版本
bash
gcc -std=c89 # 严格 C89
gcc -std=gnu89 # C89 + GNU 扩展(旧内核常用)
gcc -std=c99 # 严格 C99
gcc -std=gnu99 # C99 + GNU 扩展
gcc -std=gnu17 # 当前 GCC 默认
注意 :使用
-std=c89严格模式会禁用 GNU 扩展;-std=gnu89则两者兼得。Linux 内核从 5.x 起已迁移至 gnu11。