是否可以默认使用 UB?

Is it possible to have UB by default?

所以,我一直在阅读 the C++ standard and came to [defns.undefined] (3.27 in this C++17 draft that I'm reading. Note that while I'm citing C++17 here, I've found similar wording in other standards)——这就是未定义行为的定义。我注意到这个措辞(强调我的):

Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data

现在想想,这倒是挺有道理的。这有点像说,如果标准没有为它提供行为,它就有未定义的行为。好像是说,如果你做的事情超出了标准的范围,标准就无话可说了。有道理。

然而,这也有点奇怪,因为我一直认为未定义行为必须由标准明确声明。然而,这似乎意味着我们应该假定 未定义的行为,除非我们被告知不是这样。

如果是这种情况,那么会不会有未定义行为的实例是未定义行为,因为标准没有明确给出某些构造的行为?如果这样的事情 可能,是否有可能生成一个未定义行为的示例(仍然可以编译)因为这个措辞,或者任何属于未定义行为的示例由于某种原因,这几乎不可能建造?

If this is the case, then couldn't there be instances of Undefined Behavior that are Undefined Behavior because the Standard didn't explicitly give a behavior for some construct?

我认为这是正确的观点。如果标准 "accidentally" 省略了特定构造行为方式的规范,但我们都知道 "should" 定义明确,那么它就是标准中的一个缺陷,需要修复。另一方面,如果 "should" 是 UB 的构造,那么标准已经是 "correct"(尽管明确有好处)。

例如,如果对象的构造函数尚未开始执行或析构函数已完成,则标准未提及如果将 typeid 应用于多态 class 类型的左值会发生什么。因此,该行为未被遗漏定义。这也是 "obviously" UB 的东西。所以没有问题。

is it possible to generate an example (that would still compile) of Undefined Behavior that is Undefined Behavior because of this wording

经典的例子是通过空指针间接寻址(CWG232):

*(int*)nullptr;

[expr.unary.op]/1 表示应用间接运算符的结果是一个左值,它表示运算符的参数指向的对象,而空指针不指向任何对象.因此,通过空指针的间接访问是 UB,因为在参数不指向对象的情况下省略了行为的显式定义。