C++标准配备的用于定义一个惊人的数不清楚1种,其意味着与细微的差别或多或少相同的行为.读到这个答案后,我注意到"该程序格式错误;无需诊断"的措辞.
实现定义与未指定的行为的不同之处在于前一种情况下的实现必须清楚地记录它正在做什么(在后一种情况下,它不需要),两者都是格式良好的.未定义的行为与未指定的行为不同,因为程序是错误的(1.3.13).
否则它们都有一个共同点,就是标准不会对实现的内容做出任何假设或要求.除1.4/8之外,其中声明实现可能具有不会改变格式良好的程序的行为的扩展,但根据标准是不正确的,并且实现必须诊断使用这些,但之后可以继续编译和执行不正当的计划.
一个病态的程序否则只能定义为没有很好地形成(太棒了!).甲合式程序,在另一方面,被定义为一个附着在语法和诊断的语义规则.因此,这意味着错误的程序是打破语法或语义规则(或两者)的程序.换句话说,一个不正确的程序实际上根本不应该编译(如何以任何有意义的方式翻译例如具有错误语法的程序?).
我倾向于认为错误这个词也意味着编译器应该使用错误消息中止构建(毕竟,错误表明存在错误),但1.3.13中的"注意"部分明确允许不同的东西,包括默默地忽略问题(并且编译器显然不会因为UB 而破坏构建,大多数甚至不会默认警告).
人们可能会进一步认为错误和不正确的形式是相同的,但如果情况或该词应该是什么意思,那么标准就不会详细说明.
此外,1.4表示
符合要求的实施应[...]接受并正确执行格式良好的程序
和
如果程序包含违反不需要诊断的规则,则不要求对该程序进行实施.
换句话说,符合要求的实现必须接受格式良好的程序,但它也可能接受形式错误的程序,甚至没有警告.但是,如果程序因为使用扩展而格式不正确.
第二段建议任何与"无需诊断"相关的内容意味着规范中没有要求,这意味着它大部分等同于"未定义的行为",除非没有提到错误.
因此,使用"形成不良;无需诊断"等措辞背后的意图是什么?
"无诊断"的存在表明它与未定义的行为完全相同(或大部分相同?).此外,由于实现定义和未指定的行为被定义为格式良好,因此它必须是不同的.
另一方面,由于格式错误的程序会破坏语法/语义规则,因此它实际上不应该编译.但是,与"不需要诊断"相结合意味着允许编译器在没有警告的情况下以静默方式退出,并且之后您将无法找到可执行文件.
"形成不良;无需诊断"和"未定义行为"之间是否存在差异,或者这只是同一事物的复杂同义词?
当我写了一个关于如何在不包含 cmath 库的情况下使用 pow的答案时,我担心已经证明缺少所需标头的包含实际上是未定义的行为,但是由于我还没有发现任何同意这一事实的事实,我想强加正式问题:
缺少必需的标题,即
#include <iostream>
int main()
{
std::cout << std::pow(10, 2);
}
Run Code Online (Sandbox Code Playgroud)
在我的回答中,我倾向于肯定两个问题,但是 [using.headers] 非常令人困惑,因为未定义行为和格式错误之间的差异,不需要诊断消息。由于 [defns.well.formed] 意味着为 ODR 构建的程序是结构良好的,并且有关于何时iostream不能定义的规范pow,人们可能会争辩说这仍然是未指定的行为 ([defns.unspecified])。对于如此重要的问题,我不想仅仅依靠我的标准解释技巧来确定答案。请注意,如果代码是 UB,则接受的即唯一的其他答案不会回答,问题也不会询问它。