是Type(:: x);有效?

时间:2014-07-08 03:07:27

标签: c++ compiler-errors expression declaration language-lawyer

虽然discussing Type(identifier);语法及其声明如何,但我发现Type(::x);没有与Clang合作。我希望给定一个全局变量x,它会将::x视为表达式(::x + 2起作用)并将::x强制转换为Type。但是,它会产生编译错误。

以下是a short example

int x;

int main() {
    int(::x); //does not compile
    int(::x + 2); //compiles
}

Clang 3.5给出的编译器错误是:

  

错误:'x'的定义或重新声明无法命名全局范围

然而,GCC 4.9.0编译就好了。这段代码有效吗?

2 个答案:

答案 0 :(得分:19)

据我所知,draft C++ standard部分8.3 声明者的含义 6 表示(强调)我的前进):

  

在声明T D中,D的格式为

     

(D1)

     

包含的declarator-id的类型与包含的declarator-id的类型相同   宣言

     

T D1

     

括号不会改变嵌入式声明符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)或typename-specifier(14.6)   后面跟一个带括号的表达式列表构造一个值   给定表达式列表的指定类型。如果表达式列表是a   单表达式,类型转换表达式是等价的(in   定义,如果在意义上定义)到相应的演员   表达式(5.4)。[...]

这是明确的,因为::x + 2表达式

当声明被视为声明或表达时,涵盖的部分是6.8 歧义解决,其中包含:

  

涉及表达式语句的语法含糊不清   和声明:具有函数样式的表达式语句   显式类型转换(5.2.3),因为它最左边的子表达式可以   与第一个声明者开始的声明无法区分   a(。在这些情况下,声明是声明。 [注意:To   消除歧义,整个声明可能需要进行审查   确定它是表达式语句还是声明。这个   消除许多例子的歧义。

并提供以下示例:

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 ::D,那么T qualified-id ,如果5.1,这是clang 主要表达式的语法所涵盖的。

更新

提交gcc bug report

gcc的回应是:

  

当前G ++和EDG都将其视为有效表达式(int):: x

由于此回复意味着gcc不正确(我不同意),我提交的clang bug reportolder bug report看似相似似乎不同意clang bug report回复。

更新2

回应gcc理查德史密斯的同意,这应该被视为声明并说:

  

这并不意味着铿锵不正确;事实上,Clang是正确的   在这里,据我所见。 (我还向EDG发送了一份错误报告。)

     

那就是说,我们应该给你一个正确的解决方案,这里有一个令人烦恼的解析,这里是怎样的   消除歧义&#39;在这种情况下出错。

更新3

{{1}} confirms这是一个错误。

答案 1 :(得分:11)

对我来说,这看起来是最令人烦恼的解析。如果可以将其解析为声明。第一个可以解析为int变量(int ::x;)的声明,但::在该上下文中是非法的。第二个是一个表达式,因此编译器会进行数学运算,将其强制转换为int,并抛弃结果。

这是一个迂腐的问题,还是还有其他问题?如果您遇到了一个特定的问题,那么其他信息将为您的用例提供一种解决方法。