我发现了以下声明:
实际上,语言中所有形式的UB在求常数表达式时都需要被捕获(尽管标准库中的UB不需要被捕获)。只有在运行UB时才会发生任何事情。
(强调我的)
我的问题是,上述说法在技术上是正确的吗?
在询问用户标准如何强制执行此操作时,他们引用了exp .const#5.8,其中声明:
5。表达式E是一个核心常量表达式,除非按照抽象机器([intro.execution])的规则,对E求值将满足以下条件之一:
5.8。在[intro]中通过[cpp];
指定未定义行为的操作。
但是在阅读了上面的[expr.const#5.8]之后,我无法弄清楚这意味着语言中所有形式的UB在计算常量表达式时都需要被捕获。那么,谁能澄清一下这篇引文是如何支持(如果支持的话)上面引用的评论中的说法的?
我也读了这个,上面写着:
如果行为未定义,编译器可以接受它,拒绝它,发出警告,并根据标准,甚至崩溃,挂起或在您的计算机上安装病毒。
因此,在我看来(在阅读第一个评论时),在常量表达式求值期间的UB与运行时UB之间存在根本区别。
真相是什么?
我不明白这意味着在计算常量表达式时需要捕获语言中所有形式的UB。
不一定适用于所有形式的UB。根据上述规则,只有操作将具有[intro]通过[cpp]指定的未定义行为;.
没有其他的UB,比如在其他章节中指定的,或者不是由操作求值引起的UB,阻止表达式成为核心常量。这里有一个澄清规则:
[expr.const]如果E满足核心常量表达式的约束,但是对E的求值将求一个在[library]中通过[thread]指定的具有未定义行为的操作,或者调用va_start宏([cstdarg.syn]),则为未指定E是否为核心常数表达式
此澄清(包括在…"中指定的")语句来自问题)是对1952年缺陷报告的解决方案,措辞是c++ 17。
澄清一下,该规则导致某些UB阻止表达式成为核心常量。考虑一个规则要求表达式为常量的情况。下面是这样一个规则的例子:
[dcl.array]D1 [ constant-expression opt ] attribute-specifier-seq opt
…常量表达式必须是经过转换的常量表达式类型std:: size_t ([expr.const])。它的值N指定数组的边界,即数组中元素的数量;…
如果某个上下文要求表达式为常量,那么非常量表达式将违反该规则。在这种情况下:
[intro.compliance.general]如果程序违反了任何可诊断规则或者出现本文档中描述为"条件支持"的构造,而实现不支持该构造时,符合标准的实现应发出至少一条诊断消息.