说未定义行为"最多就是段错误"的人,该看看这段汇编
来源:blog.habets.se — 2026-10
📋 概述
有人坚持说未定义行为其实可控,最坏结果是段错误。作者用同一段代码在 GCC 16.2 与 Clang 下给出三个反例:调用一个从未被调用的函数、往地址 0 写入一个代码里根本没出现的值然后故意崩溃、或者恰好做了你期望的事。编译器没有义务去"检测"未定义行为——停机问题决定了它无法在一般情况下知道代码会不会被执行,所以它干脆假设 UB 不会发生。
🔑 核心要点
- 在 std::unreachable() 之后定义的 explode(),会被编译器挪到前面直接执行,因为"UB 不可能发生"意味着后面的控制流不可达
- 空指针写入被编译成写 0 再触发 ud2,老老实实的 99 从未出现在生成的程序里
- 同样触发 UB,*(ptr+10)=99 却照字面写进了地址 40——因为编译器没去推断这一步
- 编译器不是在"检测"UB,而是认定它不可能发生,于是不再为这个函数生成指令以节省体积
- 同一个位置触发 UB,能做出三种互不相关的事,这就是"编译器可以合法地让恶魔从你鼻子里飞出来"的字面含义
- 停机问题决定了编译器在一般情况下无法知道某段代码是否会被执行,所以不能指望它兜底
💡 金句
No compiler is obligated to "detect" UB at all.
👍 0
👎 0
← 返回 Lobsters 首页