闭坑指南 · C#经典错误
未定义行为 UB
C 里标准未规定的操作:越界、有符号溢出、use-after-free 等,编译器可任意假设。
未定义行为(Undefined Behavior)
未定义行为指 C 标准没有规定结果的操作。编译器可以:
- 优化掉「永远走不到」的分支
- 假设指针不会越界,从而重排指令
- 在
-O2下让原本「好像能跑」的代码彻底崩掉
常见 UB 来源
| 类型 | 例子 |
|------|------|
| 越界访问 | arr[10] 当 arr 长度只有 3 |
| 有符号溢出 | INT_MAX + 1 |
| 悬空指针 | free 后继续读写 |
| 未初始化读取 | 局部变量未赋值就用 |
| 违反有效指针规则 | 错误类型的指针转换 |
与「实现定义」「未指定」的区别
- 实现定义:编译器必须选一种行为并写进文档(如
char有符号与否) - 未指定:标准允许多种结果,但程序仍合法
- 未定义:什么都可能发生,包括看起来正常、崩溃、或删掉你的代码
工程建议
- 开启警告:
-Wall -Wextra -Werror(逐步收紧) - 用 Valgrind / ASan 查内存问题
- 不要写「我知道编译器会怎么优化」的代码——换版本就可能炸
下面示例只做合法访问。想感受 UB 可在本地实验越界(勿在生产代码里依赖结果)。