当前位置: 首页 > 知识库问答 >
问题:

未定义行为与格式不正确(不需要诊断消息)之间的区别

白腾
2023-03-14

C++标准为不明确的1行为提供了数量惊人的定义,这些定义的含义或多或少是相同的,但有细微的差别。阅读这个答案时,我注意到了“程序格式不正确;不需要诊断”的措辞。

实现定义与未指定行为的不同之处在于,在前一种情况下,实现必须清楚地记录它正在做什么(在后一种情况下,它不需要),两者都是格式良好的。未定义行为与未指定行为的不同之处在于程序是错误的(1.3.13)。
否则,它们都有一个共同点,即标准对实现将做什么没有任何假设或要求。除了1.4/8之外,它声明实现可能有扩展,这些扩展不会改变格式良好的程序的行为,但根据标准,它们的格式不正确,并且实现必须诊断使用这些扩展,但之后可以继续编译和执行格式不正确的程序。

否则,格式不正确的程序只能定义为格式不正确(太好了!)。另一方面,格式良好的程序被定义为遵守语法和可诊断的语义规则的程序。这将因此意味着一个格式不正确的程序是一个破坏语法或语义规则(或两者都破坏)的程序。换句话说,一个格式不正确的程序实际上根本不应该编译(例如,一个语法错误的程序如何以任何有意义的方式翻译?)。

我倾向于认为,erroneous这个词也意味着编译器应该用错误消息中止构建(毕竟,erroneous表示存在错误),但是1.3.13中的“注意”部分明确允许一些不同的东西,包括默默地忽略问题(而且编译器显然不会因为UB而中断构建,大多数甚至在默认情况下都不会发出警告)。

人们可能会进一步认为,错误和不正确的形式是一样的,但标准没有详细说明如果是这样的情况,或者这个词应该是什么意思。

此外,第1.4条规定

符合要求的实施应[...]接受并正确执行格式良好的程序

“格式不正确;不需要诊断”和“未定义的行为”之间有区别吗,还是这只是同一事物的复杂同义词?

共有1个答案

斜宁
2023-03-14

标准并不总是像我们希望的那样连贯一致,因为它是一个非常大的文档,由许多不同的人(在实践中)编写,尽管确实进行了所有校对,但不一致的地方还是会溜走。在未定义的行为(以及一般的错误)的情况下,我认为还有一个额外的问题,那就是对于大多数最基本的东西(指针等),C++标准从C中得到启发。但是C标准认为所有的错误都是未定义的行为,除非另有说明,而C++标准则试图认为所有的错误都需要诊断,除非另有说明。(尽管它们仍然必须考虑到标准忽略了指定行为的情况。)我认为这是措辞不一致的主要原因。

从全球来看,这种不一致是令人遗憾的,但总的来说,如果标准说某件事是错误的,或者是不正确的,那么它就需要一个诊断,除非标准说它不是,或者它是未定义的行为。在类似“格式不正确;不需要诊断”的情况下,“不需要诊断”是重要的,因为否则,它将需要一个诊断。至于“格式不正确;不需要诊断”和“未定义的行为”之间的区别,没有任何区别。第一种可能在代码不正确的情况下更常见,第二种是运行时问题,但不是系统的。(一个定义规则的规范--显然是编译时的问题--以“那么行为是未定义的”结束。)

 类似资料:
  • 这有道理。由于gcc确实用诊断实例化,所以我怀疑这是一个gcc bug。是这样吗?还是这段代码不需要诊断?

  • 我无法解释此程序的执行行为: 因此,当使用-O3和gcc编译它,并使用参数25运行时,它会引发一个segfault。如果没有优化,它可以正常工作。我已经对它进行了反汇编:它正在进行矢量化,编译器假设数组以16字节对齐,因此它使用。显然是UB,尽管我无法解释。我知道严格别名规则,但情况并非如此(我希望如此),因为据我所知,严格别名规则不适用于s。为什么gcc假设这个指针是对齐的?即使进行了优化,Cl

  • PowerShell的新手。尝试一些基本的例子。 我试图将TimeStamp附加到自定义消息,同时将信息写入日志文件。 输出如下所示: 有人能告诉我如何在时间戳前后去掉多余的空格吗?

  • 问题内容: 我有一个使用Doctrine 1的应用程序,并且通过生成对象的字段。它工作了好几年,但现在我有了一个新的笔记本,Doctrine尝试将字段作为字符串插入,而不是完全奇怪的普通MySQL datetime格式。 完全相同的代码可以在另一台计算机上正常运行。一切几乎都相同–两者均使用MySQL 5.6.12,PHP 5.3.15。知道我应该去哪里看吗? 更新 好的,在StackOverfl

  • 我有一个警告脚本,你基本上警告duh,它工作,但每次它发送一个不需要的消息 这是我的剧本 我很确定这是一个错误,但我只是想确定我在这里问过它,任何帮助都是感激的

  • 问题内容: MySQL根据列数据类型将表的行格式指定为固定或动态。如果表具有可变长度的列数据类型,例如TEXT或VARCHAR,则行格式是动态的;否则,它是固定的。 我的问题是,两行格式之间有什么区别?一个比另一个更有效吗? 问题答案: 差异实际上仅对MyISAM至关重要,其他存储引擎并不关心该差异。 编辑: 许多用户评论InnoDB确实在乎:链接1由steampowered,链接2由Kaan。