"int (x), 1;"是一个模棱两可的说法吗?

Is "int (x), 1;" an ambiguous statement?

本文关键字:模棱两可 一个 int      更新时间:2023-10-16
void f(int x) {
int (x), 1;
}

Clang编译了它,GCC没有。哪个编译器是正确的?

IMO,[stmt.ambig]中的措辞对此足够清楚:

将函数样式显式类型转换作为其最左边子表达式的表达式语句与第一个声明符以(开头的声明无法区分在这种情况下语句就是一个声明。

[注意如果语句在语法上不能是声明,则不存在歧义,因此不适用此规则。可能需要检查整个语句以确定是否存在这种情况。

该措辞涉及整个(expression-)语句。无法将您的语句解析为声明,因为词法1在语法上不是声明符。没有歧义:如果我们只看int(x),它可能看起来很歧义,但标准非常明确地否认,如果语句的某个前缀解析为声明,则整个语句被视为潜在声明。

事实上,核心专家在2002年就核心问题340进行了非常相似的讨论——我强调了重要的部分。在这里,我们有一个假定的声明,其中包含一个不兼容的子构造。

考虑以下程序:

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 */   
} 

问题涉及标记为/* Line X */的线,这是一个模糊的对象或函数的声明。该条款管辖这种歧义的是8.2[dcl.ambig.res]第1段,内容如下:

由于函数样式之间的相似性而产生的歧义铸造和6.8[stmt.ambig][..]中提到的声明

基于此子句,有两个对X:行中声明的可能解释

  • latt的声明声明了一个返回值为键入Lattice并接受三个参数。前两个的类型自变量是Point,每个自变量后面都跟一个多余括号中的参数名称。第三种类型无法确定参数,因为它是一个文字这会导致语法错误
  • latt的声明声明了一个对象,因为另一个选项(函数声明)将导致语法错误。请注意,"[注:"之前的最后一句不是帮助很大,因为这两个选项都是声明

Steve Adamczyk:许多人在comp.std.c++表示他们没有发现问题

原件海报回复:

我只能同意你的论点。所以有对第8.2条【dcl.ambig.res】的唯一正确解释第1段,但我不得不说,经过一些改写,该条款可以做得更清楚,比如明确指出必须考虑声明,并且函数声明比对象声明更可取。

我建议用以下产品来代替目前的第8.2条[dcl.ambig.res]第1款:

函数样式转换之间的相似性引起的歧义以及6.8[stmt.ambig][…]中提到的声明

工作组认为目前的措辞足够清楚