“未定义的行为”扩展到编译

我们都听到过警告,如果你用C或C ++调用未定义的行为 ,任何事情都可能发生。

这是否仅限于任何运行时行为,还是包含任何编译时行为? 特别是,编译器在遇到一个调用未定义行为的构造时,是否允许拒绝代码(在标准中没有其他要求的情况下这样做),甚至是崩溃?


你们都忽略了实际的定义,并专注于笔记,该标准没有要求。 ” - @ R.MartinhoFernandes

上面的消息是由给定用户在Lounge <C ++>中编写的,并且是一个非常有效的参数; 当涉及到调用未定义行为的代码时,该标准没有强加任何要求。


! ! !

未定义的行为甚至延伸到编译器解析输入数据(即代码)的最远角,正如以下来自C ++ 11和C99标准的引文所验证的那样。

用一句话回答你的问题 ;

  • 未定义的行为不限于运行时执行,并且在编译过程中允许“以文档化的方式表征环境”1

  • “以文档化的方式表现环境”是一种奇怪的陈述,你几乎可以编写一个编译器记录它可能在任何给定的代码(这是无效的)时崩溃,以授予它随时崩溃的可能性。

    1.引用C ++ 11 / C99标准


    C ++ 11

    1.3.24 [defns.undefined]

    未定义的行为; 本国际标准对此没有要求的行为

    [ 注意:

    当本标准忽略任何行为的明确定义或程序使用错误构造或错误数据时,可能会出现未定义的行为。

    允许的未定义的行为范围从完全忽略情况,具有不可预测的结果在翻译程序执行 期间以文档化的方式表现环境特征(发布或不发布诊断消息),终止翻译或执行(发布的诊断消息)。

    许多错误的程序结构不会产生未定义的行为; 他们需要被诊断。

    - 结束注释]


    C99

    3.4.3 - 未定义的行为

  • 行为,在使用不可移植或错误的程序结构或错误数据时,对于该行为,“国际标准”没有规定任何要求

  • 注意可能存在未定义的行为范围,包括忽略完全不可预知的结果在翻译或程序执行期间以文档化的方式表现环境特征( 无论是否发布诊断消息 ), 终止翻译或执行 (使用发布诊断消息)。


  • 如果行为未定义,编译器可以接受它,拒绝它,发出警告,并根据标准甚至在计算机上崩溃,挂起或安装病毒。

    在实践中,这并不意味着如果你正在编写一个编译器,你应该有意识地做这些事情,但是,例如,如果性能优势证明它可以,那么你可以使用一种算法来处理已定义的案例,崩溃或挂起未定义的算法。

    尽管如此,一个有信誉的编译器会避免这种情况,或者至少有很好的文档记录。


    它不限于运行时行为。 根据ISO / IEC 14882,第一版,1998-09-01,1.3.12,在一份说明中(非常规性):“允许未定义的行为范围从......到在翻译或编程执行期间以文件化方式表现的环境“。 换句话说,标准说实施可以做任何操作系统(或其他环境)允许的,只要它被记录下来。

    链接地址: http://www.djcxy.com/p/79921.html

    上一篇: Does "undefined behaviour" extend to compile

    下一篇: Can branches with undefined behavior be assumed unreachable and optimized as dead code?