C++ 标准是否指定在某些情况下编译应该因错误而失败?
Does the C++ standard specify that for some cases the compiling should fail with an error?
我正在检查有关缩小转换的标准,我认为对于缩小转换应该触发错误。因为 standard 说:
[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations. — end note ]
我认为"not allowed"的描述意味着编译应该失败。
但是有人告诉我here只是说"the program is ill-formed",标准不会要求编译必须失败。
if a narrowing conversion (see below) is required to convert the
element to T, the program is ill-formed.
所以我的问题是:标准是否指定是否应该生成错误或警告?或者在某些情况下编译应该失败?从编译器的角度来说,让程序编译通过,只给出一些警告就可以了吗?
顺便说一句:Clang 4.0.0 and Gcc 7.0.0 行为不同。
float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d}; // Error for Clang, warning for GCC
如果程序不是病式的(并且没有 UB),编译器必须生成
一个可执行的输出。如果程序是格式错误的,则标准不
有无输出限制
如果程序格式错误,并且不是 NDR,则必须进行 诊断
生产的。该标准不区分警告或错误。
对格式错误的程序的唯一要求是编译器必须 "issue a diagnostic",其中 "diagnostic" 具有实现定义的含义。完成后,编译器可以自由地继续编译代码。这是实现特定行为的主要挂钩。
标准不使用术语"error"和"warning",它只讨论编译器必须"issue a diagnostic"的情况。
在您的示例中,如果程序是 "ill-formed",编译器需要以某种方式告诉您 - 发出诊断。
在那之后,它可以做任何它喜欢的事情——包括编译和 运行 程序。该标准仅指定符合代码会发生什么,其他所有内容均未定义。然后,正如我们所知,任何事情都有可能发生。
标准中的注释是非规范的,不影响语言的定义。因此,从语言律师的角度来看,您第一条引文中的注释并不重要。
话虽如此,我认为你的两段引文意思是一样的。 "ill formed program" 是不根据语法规则构造的, 可诊断语义规则 和标准(强调我的)的一个定义规则。如果某个语义是"not allowed",那仅仅意味着它违反了语言的可诊断语义规则,因此仅仅意味着它是错误的。
编译器需要对格式错误的程序发出诊断。之后,编译器可以做任何它想做的事。该标准未指定编译必须失败的任何条件。
如果程序不是病式的,编译器必须产生可执行的输出。如果程序不包含 UB,则可执行文件的行为必须与标准描述的抽象机一样。如果它确实包含 UB,则可执行文件可以执行任何操作。
如果程序格式错误且不需要诊断,编译器可以做任何事情。它可以生成可执行输出,也可以不生成。该可执行输出可以做任何事情。例如,它可以设计一个似乎符合代码意图的程序。
编译器可以随时打印诊断信息。
编译器在某些情况下必须打印诊断信息。 "Most" 格式错误的程序需要诊断。诊断到底是什么是实现定义的。已注意到打印单个空白换行符或 space 是标准下的有效诊断。
这将被认为是实施质量低下。
一旦存在需要诊断的格式错误的程序时打印诊断,编译器就可以自由地做任何事情。它可以生成与您的要求有些匹配的可执行文件,可以生成可以执行任何操作的可执行文件,也可以不生成可执行文件。
标准不区分警告和错误。
格式错误的程序需要打印警告的诊断,然后继续编译,不违反标准。
格式错误的程序需要打印错误的诊断,然后不继续编译,不违反标准。
不需要诊断的格式错误的程序可以打印诊断。它可以选择是否生成可执行文件。可执行文件可以做一些合理或不合理的事情。
一个格式良好的程序可以让编译器发出诊断。此诊断可描述为警告。它也可以被描述为错误,但编译器必须生成可执行文件,并且可执行文件必须执行标准要求的操作。
我正在检查有关缩小转换的标准,我认为对于缩小转换应该触发错误。因为 standard 说:
[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations. — end note ]
我认为"not allowed"的描述意味着编译应该失败。
但是有人告诉我here只是说"the program is ill-formed",标准不会要求编译必须失败。
if a narrowing conversion (see below) is required to convert the element to T, the program is ill-formed.
所以我的问题是:标准是否指定是否应该生成错误或警告?或者在某些情况下编译应该失败?从编译器的角度来说,让程序编译通过,只给出一些警告就可以了吗?
顺便说一句:Clang 4.0.0 and Gcc 7.0.0 行为不同。
float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d}; // Error for Clang, warning for GCC
如果程序不是病式的(并且没有 UB),编译器必须生成 一个可执行的输出。如果程序是格式错误的,则标准不 有无输出限制
如果程序格式错误,并且不是 NDR,则必须进行 诊断 生产的。该标准不区分警告或错误。
对格式错误的程序的唯一要求是编译器必须 "issue a diagnostic",其中 "diagnostic" 具有实现定义的含义。完成后,编译器可以自由地继续编译代码。这是实现特定行为的主要挂钩。
标准不使用术语"error"和"warning",它只讨论编译器必须"issue a diagnostic"的情况。
在您的示例中,如果程序是 "ill-formed",编译器需要以某种方式告诉您 - 发出诊断。
在那之后,它可以做任何它喜欢的事情——包括编译和 运行 程序。该标准仅指定符合代码会发生什么,其他所有内容均未定义。然后,正如我们所知,任何事情都有可能发生。
标准中的注释是非规范的,不影响语言的定义。因此,从语言律师的角度来看,您第一条引文中的注释并不重要。
话虽如此,我认为你的两段引文意思是一样的。 "ill formed program" 是不根据语法规则构造的, 可诊断语义规则 和标准(强调我的)的一个定义规则。如果某个语义是"not allowed",那仅仅意味着它违反了语言的可诊断语义规则,因此仅仅意味着它是错误的。
编译器需要对格式错误的程序发出诊断。之后,编译器可以做任何它想做的事。该标准未指定编译必须失败的任何条件。
如果程序不是病式的,编译器必须产生可执行的输出。如果程序不包含 UB,则可执行文件的行为必须与标准描述的抽象机一样。如果它确实包含 UB,则可执行文件可以执行任何操作。
如果程序格式错误且不需要诊断,编译器可以做任何事情。它可以生成可执行输出,也可以不生成。该可执行输出可以做任何事情。例如,它可以设计一个似乎符合代码意图的程序。
编译器可以随时打印诊断信息。
编译器在某些情况下必须打印诊断信息。 "Most" 格式错误的程序需要诊断。诊断到底是什么是实现定义的。已注意到打印单个空白换行符或 space 是标准下的有效诊断。
这将被认为是实施质量低下。
一旦存在需要诊断的格式错误的程序时打印诊断,编译器就可以自由地做任何事情。它可以生成与您的要求有些匹配的可执行文件,可以生成可以执行任何操作的可执行文件,也可以不生成可执行文件。
标准不区分警告和错误。
格式错误的程序需要打印警告的诊断,然后继续编译,不违反标准。
格式错误的程序需要打印错误的诊断,然后不继续编译,不违反标准。
不需要诊断的格式错误的程序可以打印诊断。它可以选择是否生成可执行文件。可执行文件可以做一些合理或不合理的事情。
一个格式良好的程序可以让编译器发出诊断。此诊断可描述为警告。它也可以被描述为错误,但编译器必须生成可执行文件,并且可执行文件必须执行标准要求的操作。