void f(int x) {
int (x), 1;
}
Clang compiles it, GCC doesn't. Which compiler is correct?
答案 0 :(得分:17)
IMO,[stmt.ambig]中的措辞对此很清楚:
具有函数样式显式类型转换的表达式语句 ,因为其最左侧的子表达式与第一个声明符以{开头的声明无法区分{1}} 即可。 在这些情况下声明是声明。
[注意:如果语句在语法上不能成为声明,则不存在歧义,因此该规则不适用。可能需要检查整个陈述以确定是否属于这种情况。
措辞说明了整个(表达式)陈述。
您的语句无法解析为声明,因为词法(
在语法上不是声明符。没有含糊之处:如果我们只看1
,它可能看起来很模糊,但标准明确否认如果语句的某些前缀作为声明解析,则整个语句被认为是潜在的声明。
事实上,核心专家在2002年对core issue 340进行了非常类似的讨论 - 我强调了重要的一点。在这里,我们再次假设包含不兼容的子构造的声明。
考虑以下计划:
int(x)
问题涉及标记为
struct Point { Point(int){} }; struct Lattice { Lattice(Point, Point, int){} }; int main(void) { int a, b; Lattice latt(Point(a), Point(b), 3); /* Line X */ }
的行,这是一个含糊不清的行 对象或函数的声明。该条款 管理这种歧义的是8.2 [dcl.ambig.res]第1段,并写着:功能风格之间相似性产生的模糊性 演员和6.8 [stmt.ambig] [..]
中提到的声明根据这一条款,有两个 第
/* Line X */
行中对声明的可能解释:
X
的声明声明了一个返回值为的函数 输入latt
并取三个参数。前两种的类型 参数是Lattice
,每个参数后跟一个 冗余括号中的参数名称。第三种类型 参数无法确定,因为它是一个文字。这样会 导致语法错误。- latt的声明声明了一个对象, 因为另一个选项(函数声明)会导致a 语法错误。请注意,“[注意:”之前的最后一句不是 很有帮助,因为这两个选项都是声明。
Steve Adamczyk:很多人回复了这篇文章 comp.std.c ++说他们没有看到问题。
原作 海报回复说:
我不能做任何事情,只能同意你的论证。所以有 第8.2条只有一个正确的解释[dcl.ambig.res] 第1段,但我必须说一些重新措辞,该条款 可以做得更清楚,就像明确说明整个 必须考虑声明和功能声明 比对象声明更受欢迎。
我想建议以下作为当前的替代品 第8.2条[dcl.ambig.res]第1段:
由functionstyle演员之间的相似性引起的歧义 以及6.8 [stmt.ambig] [...]
中提到的声明工作组认为目前的措辞足够清晰。