C++26 让平凡死循环不再属于未定义行为
来源: sandordargo.com — 2026-09-16
概述
在 C++26 之前,像 while (true); 这种没有副作用的死循环属于未定义行为,编译器有权假定它会终止,Clang 就会把循环优化掉,导致执行落到链接器安排在后面的函数上。C 语言早在 C11 就为控制表达式是常量的循环开了例外,C++ 一直没有跟进。P2809R3 在 C++26 里以「平凡死循环」这个更窄的定义修掉了它:循环体必须为空,控制表达式必须是求值为真的常量表达式,此时循环体会被替换成一次 std::this_thread::yield()。
核心要点
- 旧规则来自 C++11 的前向进展保证:实现可以假定线程最终会终止、做 I/O、访问 volatile 或执行同步操作。
- 后果并不停留在纸面:Clang 会删掉循环,把 main 的落点交给链接器放在后面的函数,于是打印出 Hello world。
- 嵌入式与内核代码里 while (true); 是常见的「出错即停机」写法,优化掉后设备会在损坏状态下继续运行。
- 新定义刻意比 C 的规则更窄,因为 C 保护的范围太广,会抑制有价值的优化。
- 修正同时被接受为缺陷报告,因此较新的编译器在 C++20 模式下也可能不再复现旧行为。
金句
这不是编译器 bug,它只是未定义行为——好在还没召出鼻子里钻出来的恶魔。
👍 0
👎 0
返回 Lobsters 首页