为什么常量表达式会排除未定义的行为?

为什么常量表达式会排除未定义的行为?

我正在研究核心常量表达式*中允许的内容,这在C ++标准草案的5.19 常量表达式2段中有所描述:

条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式(3.2),但是未评估的逻辑AND(5.14),逻辑OR(5.15)和条件(5.16)操作的子表达式不考虑[注意:重载的运算符调用函数。-end note]:

并列出随后的子弹中的排除项并包括(强调我的):

具有未定义行为的操作 [注意:包括,例如,有符号整数溢出(第5条),某些指针算术(5.7),除零(5.6)或某些移位操作(5.8) - 结束注释];

?为什么常量表达式需要此子句来涵盖未定义的行为常量表达式是否有一些特殊的东西需要未定义的行为才能在排除中进行特殊划分?

拥有这个条款是否给了我们没有它的任何优势或工具?

作为参考,这看起来像广义常量表达式提案的最新修订版。


德玛西亚99
浏览 683回答 3
3回答

一只名叫tom的猫

当我们谈论未定义的行为时,重要的是要记住标准为这些情况留下了未定义的行为。它并不禁止实施更强有力的保证。例如,一些实现可以保证有符号整数溢出包围,而其他实现可以保证饱和。要求编译器处理涉及未定义行为的常量表达式将限制实现可以做出的保证,限制它们产生一些没有副作用的值(标准称为不确定值)。这排除了现实世界中发现的许多延伸保证。例如,一些实现或伴随标准(即POSIX)可以将积分除以零的行为定义为生成信号。如果表达式是在编译时计算的,那么这会产生副作用。因此,这些表达式在编译时被拒绝,以避免在执行环境中丢失副作用。

慕婉清6462132

还有一点是从常量表达式中排除未定义的行为:根据定义,常量表达式应该由编译器在编译时进行评估。允许常量表达式来调用未定义的行为将允许编译器本身显示未定义的行为。而且,编译硬盘驱动器的编译器因为编译了一些恶意代码而不是你想拥有的。
打开App,查看更多内容
随时随地看视频慕课网APP