是否缺少必需的包含未定义行为?

Sup*_*kus 5 c++ include undefined-behavior language-lawyer

当我写了一个关于如何在不包含 cmath 库的情况下使用 pow的答案时,我担心已经证明缺少所需标头的包含实际上是未定义的行为,但是由于我还没有发现任何同意这一事实的事实,我想强加正式问题:

缺少必需的标题,即

#include <iostream>

int main()
{
    std::cout << std::pow(10, 2);
}
Run Code Online (Sandbox Code Playgroud)
  1. 格式错误( [defns.ill.formed] )代码?
  2. 调用未定义的行为( [defns.undefined] )?
  3. 如果不是1和2,是未指定行为[defns.unspecified]还是实现定义行为[defns.impl.defined]?
  4. 如果不是 1. 即如果此代码格式良好,这与 [using.headers] 和 [intro.compliance] 是否“接受并正确执行格式良好的程序”相矛盾?

在我的回答中,我倾向于肯定两个问题,但是 [using.headers] 非常令人困惑,因为未定义行为和格式错误之间差异,不需要诊断消息。由于 [defns.well.formed] 意味着为 ODR 构建的程序是结构良好的,并且有关于何时iostream不能定义的规范pow,人们可能会争辩说这仍然是未指定的行为 ([defns.unspecified])。对于如此重要​​的问题,我不想仅仅依靠我的标准解释技巧来确定答案。请注意,如果代码是 UB,则接受的即唯一的其他答案不会回答,问题也不会询问它。

Dav*_*ing 2

指定该程序是格式正确还是格式错误(需要进行诊断,因为名称查找不会找到\xe2\x80\x99t pow)。这种可能性是由一个 C++ 头文件可能包含另一个C++ 头文件的声明引起的,该声明授予实现权限,以便为该程序提供两种可能的解释之一

\n\n

几个类似的规则(例如,模板必须至少有一个有效的潜在专业化)描述为使程序格式错误,不需要诊断,但在这种情况下,自由度不会扩展到实现(这可以说是更好的) 。也就是说,只要实现至少发出一条诊断消息,就允许它以任意方式处理格式错误的程序,因此将这种情况与真正的未定义行为分组并不是完全不合理的,即使这些症状在实践中有所不同。

\n