据我所知,draft C++ standard 部分 8.3 声明符的含义 段落 6 涵盖了这一点(强调我的未来):
在声明 T D 中,其中 D 具有以下形式
(D1)
包含的 declarator-id 的类型与包含的 declarator-id 的类型相同
声明
T D1
括号不会改变嵌入的 declarator-id 的类型,但它们可以改变复杂的绑定
声明符。
所以:
int(::x);
相当于:
int ::x ;
这显然是无效的,这也会产生相同的错误。所以gcc 4.9 在这里是不正确的,但由于这看起来在稍后发布的gcc 4.8.3 中已修复,我希望这也将在4.9 的后续版本中修复。虽然我在gcc 4.8.3 bugs fixed list 中没有看到任何与此问题的明显匹配项,但他们并没有声称这是一个完整的列表。
第二种情况是函数显式类型转换,在 5.2.3 部分中进行了介绍 显式类型转换(函数表示法) 说:
简单类型说明符 (7.1.6.2) 或类型名称说明符 (14.6)
后跟一个带括号的表达式列表构造一个值
给定表达式列表的指定类型。如果表达式列表是
单个表达式,类型转换表达式是等价的(在
定义性,如果在含义中定义)到相应的演员表
表达式 (5.4).[...]
这是明确的,因为::x + 2 是一个表达式。
涵盖何时将语句视为声明或表达式的部分是6.8 歧义解决,它表示:
涉及表达式语句的语法存在歧义
和声明:具有函数样式的表达式语句
显式类型转换(5.2.3)作为其最左边的子表达式可以是
与第一个声明符开始的声明没有区别
带有 (。在这些情况下,该语句是一个声明。 [注意:要
消除歧义,可能需要检查整个陈述以
确定它是表达式语句还是声明。这
消除许多例子的歧义。
并提供以下示例:
T(a)->m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5)<<c; // expression-statement
T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; // declaration
T(*g)(double(3)); // declaration
注意:如果T 是一个类,那么如果没有(),那么T ::D 是一个qualified-id,它包含在5.1 基本表达式的语法。
更新
提交了gcc bug report。
gcc 的回应是:
当前 G++ 和 EDG 都将其视为有效表达式 (int)::x
由于此回复暗示 clang 不正确(我不同意),我提交了 clang bug report 和 older bug report 看起来相似,似乎不同意 gcc 回复.
更新 2
在回复clang bug report 时,Richard Smith 同意这应该被视为一项声明,并说:
这并不意味着 clang 是不正确的;事实上,Clang 是正确的
在这里,据我所知。 (我还向 EDG 发送了错误报告。)
也就是说,我们应该给出正确的“你遇到了一个令人烦恼的解析,这就是如何
在这种情况下消除歧义。
更新 3
gccconfirms 这是一个错误。