首页 > 解决方案 > 是否缺少必需的包含未定义行为?

问题描述

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

缺少必需的标头,即

#include <iostream>

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

在我的回答中,我倾向于肯定这两个问题,但是 [using.headers] 非常令人困惑,因为Undefined Behavior 和 Ill-formed, no diagnostic message required 之间的差异。由于 [defns.well.formed] 暗示为 ODR 构建的程序格式正确,并且当示例iostream不能定义时有规范pow,人们可能会争辩说这仍然是未指定的行为 ([defns.unspecified])。我不想仅仅依靠我的标准解释技能来为如此重要的问题提供明确的答案。请注意,如果代码是 UB,则接受的,即唯一的其他答案不会回答,问题也不会问它。

标签: c++includelanguage-lawyerundefined-behavior

解决方案


指定此程序是格式正确还是格式错误(需要诊断,因为名称查找未找到pow)。可能性来自于一个 C++ 头文件可能包含另一个头文件的声明,该声明授予实现的权限,以便为该程序提供两种可能的解释中的任何一种。

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


推荐阅读