是否保证在计算常量表达式时捕获所有形式的未定义行为?



我发现了以下声明:

实际上,语言中所有形式的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]

如果程序违反了任何可诊断规则或者出现本文档中描述为"条件支持"的构造,而实现不支持该构造时,符合标准的实现应发出至少一条诊断消息.

相关内容

  • 没有找到相关文章