作为user Tony points out,C ++标准第1.3.12节中有[注]
允许的未定义行为包括完全忽略不可预测的结果,在翻译或程序执行过程中以环境特征的文档化方式表现......
这是否与UB的定义相矛盾? ...此国际标准没有要求 ?我的意思是他们说“没有要求”,然后说“允许的UB” - 就在同一段中。
该笔记应如何解释?它确实以任何方式限制UB吗?
答案 0 :(得分:7)
来自ISO / IEC指令Part 3的§6.5.1:
集成在中的注释和示例 只能使用标准文本 提供更多信息 旨在协助理解 或使用标准,不得 包含它的规定 必须符合才能 能够声称遵守 标准。
因此,它完全是非规范性的(非约束性),仅用于可能的澄清。
答案 1 :(得分:6)
由于注释不是规范性的,因此不会以任何方式限制UB。这只是一个澄清,一个实现可以使用一些正式导致UB作为文档扩展的结构,尽管任何依赖于这种细节的程序当然都不能安全地移植到其他环境中。
答案 2 :(得分:2)
本说明解释了实现在遇到没有定义行为的代码时可能会执行的操作。 “允许”一词并非旨在限制,而是给出了一些常见行为的例子。
有趣的是,编译器几乎总是需要编译一些东西!考虑这段代码:
void f() { 1 / 0; }
翻译人员在遇到这种情况时的行为没有明确定义,但它不能做任何喜欢的事情!实际上,如果它是一个编译器,仍然需要编译这个编译单元。这是因为包含此功能的程序的行为仍然可以很好地定义!编译器无法知道函数是否被调用。事实上,这个问题出现在函数是“main()”的地方,并且控制肯定会流过零分区,结果是编译器不允许拒绝该程序。原因是:程序仍然很好,并且需要符合标准的编译器接受所有格式良好的程序(并拒绝所有格式错误的程序并发出诊断错误消息,除非另有说明)。
这不容易变得格格不入,因为很难准确地指出智能编译器在检测何时必须进行除零时需要检测。
有趣的是,标准声称它“没有要求”实际上非常接近于错误。它是支持单独编译的编译系统的特性,它无法检测到实际上是否执行了没有明确定义的行为的代码,因此编译器实际上是必需无论如何编译一些东西,因为如果程序具有未定义的行为,它就无法推断出来。