C++ 标准是否指定在某些情况下编译应失败并出现错误?

问题描述 投票:0回答:5

我正在检查有关缩小转换的标准,我认为对于缩小转换,应该触发错误。因为标准说:

[ 注意:如上所述,在列表初始化的顶层不允许进行此类转换。 — 尾注]

我认为“不允许”的描述意味着编译应该失败。

但有人告诉我,这里只是说“程序格式错误”,标准不会要求编译必须失败。

如果需要缩小转换(见下文)来转换 元素为 T,程序格式错误。

所以我的问题是:标准是否指定是否应该生成错误或警告?或者在某些情况下编译应该失败?从编译器的角度来说,让程序编译并给出一些警告就可以了吗?

顺便说一句:Clang 4.0.0Gcc 7.0.0 的行为不同。

float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d};     // Error for Clang, warning for GCC
c++ type-conversion language-lawyer
5个回答
31
投票

该标准不使用术语“错误”和“警告”,它只讨论编译器必须“发出诊断”的情况。

在您的示例中,如果程序“格式错误”,则编译器需要以某种方式告诉您 - 发出诊断。

之后,它可以做任何它喜欢做的事情 - 包括无论如何编译和运行程序。该标准仅指定了符合代码会发生什么,其他一切都未定义。然后,正如我们所知,任何事情都可能发生。


16
投票

格式错误的程序的唯一要求是编译器必须“发出诊断”,其中“诊断”具有实现定义的含义。完成此操作后,编译器可以继续编译代码。这是特定于实现的行为的主要钩子。


5
投票

如果程序不是格式错误的,编译器必须产生可执行输出。如果程序不包含 UB,则可执行文件的行为必须与标准描述的抽象机的行为相同。如果它确实包含 UB,则可执行文件可以执行任何操作。

如果程序格式错误且不需要诊断,编译器可以执行任何操作。它可以产生可执行的输出,也可以不产生。该可执行输出可以做任何事情。例如,它可以设计一个看起来符合代码意图的程序。

编译器可以随时打印诊断信息。

在某些情况下,编译器必须打印诊断信息。 “大多数”格式错误的程序都需要诊断。诊断到底是什么是由实现定义的。值得注意的是,打印单个空白换行符或空格是标准下的有效诊断。

这将被视为实施质量较差。

当存在需要诊断的格式不正确的程序时,一旦打印出诊断信息,编译器就可以自由地执行任何操作。它可以生成一个在某种程度上符合您要求的可执行文件,生成一个执行它想要的任何操作的可执行文件,或者不生成任何可执行文件。

该标准不区分警告和错误。

需要诊断并打印警告然后继续编译的格式错误的程序并不违反标准。

格式错误的程序需要打印错误的诊断,然后不会继续编译,并不违反标准。

不需要诊断的格式错误的程序可以打印诊断信息。它可以选择是否生成可执行文件。可执行文件可以做一些合理的事情,也可以不做一些不合理的事情。

结构良好的程序可以让编译器发出诊断。此诊断可以描述为警告。它也可以被描述为错误,但编译器必须生成可执行文件,并且可执行文件必须执行标准要求的操作。


2
投票

如果程序不是格式错误的(并且没有 UB),编译器必须生成 可执行的输出。如果程序is 格式错误,则标准不构成任何问题 限制是否有输出。

如果程序格式错误,且不是 NDR,则必须进行 诊断 产生的。该标准不区分警告或错误。


2
投票

标准中的注释是非规范性的,不影响语言的定义。因此,从语言律师的角度来看,您第一个引文中的注释并不重要。

话虽如此,我认为你的两句话的意思是一样的。 “格式错误的程序”是指未根据标准的语法规则、可诊断的语义规则和一个定义规则(强调我的)构建的程序。如果某个语义“不允许”,则意味着它违反了语言的可诊断语义规则,因此仅意味着它的格式不正确。

编译器需要对格式错误的程序发出诊断。之后,编译器就可以做任何它想做的事情了。该标准没有指定编译必须失败的任何条件。

© www.soinside.com 2019 - 2024. All rights reserved.