是Type(:: x); 有效?

chr*_*ris 22 c++ expression compiler-errors declaration language-lawyer

虽然讨论Type(identifier);语法和它是如何声明,我碰到Type(::x);不锵工作.我希望给定一个全局变量x,它将被::x视为一个表达式(::x + 2作品)并转换::xType.但是,它给出了编译器错误.

这是一个简短的例子:

int x;

int main() {
    int(::x); //does not compile
    int(::x + 2); //compiles
}
Run Code Online (Sandbox Code Playgroud)

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

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

但是,GCC 4.9.0编译就好了.这段代码有效吗?

Sha*_*our 19

据我所知,C++草案标准部分涵盖了8.3 声明者6段的含义(强调我的未来):

在TD的声明中,D表格

(D1)

包含的declarator-id的类型与声明中包含的declarator-id的类型相同

T D1

括号不会改变嵌入式声明符id的类型,但它们可以改变复杂声明符的绑定.

所以:

int(::x);
Run Code Online (Sandbox Code Playgroud)

相当于:

int ::x ;
Run Code Online (Sandbox Code Playgroud)

这显然是无效的,这也会产生同样的错误.所以gcc 4.9这里不正确,但因为这看起来固定在gcc 4.8.3后来发布的,我希望这也可以在以后的版本中修复4.9.虽然我没有在gcc 4.8.3错误修复列表中看到这个问题有任何明显的匹配,但他们并没有声称它是一个完整的列表.

第二种情况是功能显式类型转换,在5.2.3 显式类型转换(功能表示法)部分中介绍,该部分说:

简单类型说明符(7.1.6.2)或类型名称说明符(14.6)后跟带括号的表达式列表,在给定表达式列表的情况下构造指定类型的值.如果表达式列表是单个表达式,则类型转换表达式与相应的强制转换表达式(5.4)等效(在定义中,如果在意义上定义).[...]

这是明确的,因为它::x + 2是一个表达式.

涵盖何时将声明视为声明或表达的部分是6.8 歧义解决方案,其中说:

有在语法的歧义涉及表达语句和声明:用一个函数式的明确的类型转换(5.2.3)为其中所述第一声明符与(开始它的最左边的子表达式可以是从声明不可区分的expressionstatement 在那些case语句是声明. [注意:为了消除歧义,可能必须检查整个语句以确定它是表达式语句还是声明.这消除了很多例子的歧义.

并提供以下示例:

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
Run Code Online (Sandbox Code Playgroud)

注意:如果没有()then,那么在成为的情况下,then T ::D是一个qualified-id,这是一个涵盖在主表达式语法中的.T5.1

更新

提交了一份gcc bug报告.

gcc的回答是:

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

由于这个反应意味着clang不正确(我不同意),我提交了一个clang bug报告,旧的bug报告看起来很相似,似乎不同意gcc响应.

更新2

为了回应clang bug report理查德史密斯的同意,这应该被视为一个声明,并说:

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

也就是说,在这种情况下,我们应该给出一个正确的'你打了一个令人烦恼的解析,这里是如何消除歧义'.

更新3

gcc 确认这是一个错误.


Mar*_*k B 11

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

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