因为C和C++社区往往非常强调未定义行为的不可预测性以及编译器在遇到未定义行为时可以使程序做任何事情的想法,我原以为标准对于未定义行为的行为没有任何限制。
但是,C++标准中的相关引用似乎是: > [C++14:defns.undefined]:[..]可接受的未定义行为范围从完全忽略情况及带有不可预测结果的行为,到在翻译或程序执行期间表现出特定环境的文档化方式(无论是否发出诊断消息),到终止翻译或执行(附带发出诊断消息)[...]。
实际上,这里指定了一小组可能的选项:
- 忽视情况——是的,标准继续说这将会有“不可预测的结果”,但这并不意味着编译器会插入代码(我假设这是产生鼻妖的先决条件)。
- 表现出环境特征的已记录方式——这听起来相对无害。(我肯定没有听说过任何鼻妖的已记录案例。)
- 终止翻译或执行——并附带诊断信息。如果所有未定义的行为都能如此友好地表现就好了。
我认为在大多数情况下,编译器选择忽略未定义的行为;例如,在读取未初始化的内存时,插入任何代码以确保一致性行为可能会适得其反。我想奇怪类型的未定义行为(例如“时间旅行”)将属于第二类——但这要求这些行为被记录并“具有环境特征”(所以我猜鼻妖只会被恶魔计算机产生?)。
我是否误解了定义?这些只是可能构成未定义行为的示例,而不是一份全面的选项清单吗?声称“任何事情都可能发生”仅仅是忽略情况的意外副作用吗?两个澄清小点:
- 我认为对于原始问题,对于大多数人来说都很清楚,但我仍然会说明:我确实意识到“鼻妖”是开玩笑的。
- 请不要写一个(另一个)回答来解释UB允许特定于平台的编译器优化,除非您还解释它如何允许实现定义行为所不允许的优化。
这个问题并不是讨论未定义行为的优缺点的论坛,但它似乎变成了这样的讨论。无论如何,对于那些认为这是一个重要话题的人来说,这个关于假想C编译器没有未定义行为的帖子可能会更有兴趣。