C语言历史版本和gnu扩展版本

一、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),函数原型、voidconstvolatile
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 nullptrbool/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 标准 第一个官方标准,函数原型、voidconstvolatile
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 标准 nullptrbool 关键字、二进制字面量、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。

相关推荐
To_OC1 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC1 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK1 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌2 天前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局2 天前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象2 天前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法
统计实现局2 天前
对称不定分解(Bunch-Kaufman):为什么 Cholesky 不够用
算法
统计实现局2 天前
dqrsl 拆解:拿着 QR 结果能算出哪 5 种东西
算法
统计实现局2 天前
为什么 Cholesky 求逆比 Gauss-Jordan 快一倍——行列式溢出防护详
算法