是Type(:: x);有效? [英] Is Type(::x); valid?

查看:197
本文介绍了是Type(:: x);有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

讨论 Type(identifier); 语法和它是一个声明,我遇到了 Type(:: x); 。我希望给定一个全局变量 x ,它会将 :: x 作为一个表达式( :: x + 2 ),并将 :: x 转换为类型。但是,它会产生编译器错误。

While discussing the Type(identifier); syntax and how it's a declaration, I came across Type(::x); not working with Clang. I would expect that given a global variable x, it would treat ::x as an expression (::x + 2 works) and cast ::x to Type. However, it gives a compiler error.

这里是一个简短的例子

int x;

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

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

The compiler error given by Clang 3.5 is:


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

error: definition or redeclaration of 'x' cannot name the global scope

GCC 4.9.0,但是,编译这个很好。此代码是否有效?

GCC 4.9.0, however, compiles this just fine. Is this code valid or not?

推荐答案

据我所知,草案C ++标准部分 8.3 的含义

As far as I can tell this is covered by draft C++ standard section 8.3 Meaning of declarators paragraph 6 which says (emphasis mine going forward):


在声明TD中,D的格式为

In a declaration T D where D has the form

(D1)

所包含的declarator-id的类型与
中所包含的declarator-id的类型相同。

the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration

T D1

括号不会改变嵌入的declarator-id的类型,但它们可以改变复合
声明符的绑定。

Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.

所以:

int(::x);

等效于:

int ::x ;

这显然是无效的,这也产生相同的错误。所以 gcc 4.9 在这里不正确,但因为这看起来固定在稍后发布的 gcc 4.8.3 期望这在 4.9 的更高版本中也是固定的。虽然我在 gcc 4.8.3错误固定列表,但他们不声称它是一个完整的列表。

which is clearly not valid, and this produces the same error as well. So gcc 4.9 is not correct here but since this looks fixed in the gcc 4.8.3 which was released later I would expect this to be fixed in later releases of 4.9 as well. Although I don't see any obvious matches for this issue in the gcc 4.8.3 bugs fixed list but they don't claim it is a complete list.

第二种情况是一个功能显式 5.2.3 显式类型转换(功能符号)中说明的

The second case is a functional explicit type conversion which is covered in section 5.2.3 Explicit type conversion (functional notation) which says:


一个简单类型说明符(7.1.6.2)或typename-specifier(14.6)
后跟一个括号表达式列表构造
的值给定表达式列表的指定类型。如果表达式列表是一个
单个表达式,则类型转换表达式等效于(
定义,如果定义的话)对应的转换
表达式(5.4)。 ]

A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).[...]

这是明确的,因为 :: x + 2 >

This is unambiguous since ::x + 2 is an expression.

覆盖语句被视为声明或表达式的部分 6.8 歧义解析,其中包含:

The section that covers when a statement is considered a declaration or a expression is 6.8 Ambiguity resolution which says:


语法中含有表达式语句的歧义
和声明:带有函数式
显式类型转换(5.2.3)作为其最左子表达式的表达式语句可以是
与第一个声明符开始的声明不可区分。
用一个(。 strong>在这些情况下,语句是一个声明。 [注意:要
消除歧义,整个语句可能需要检查
确定它是一个表达式语句还是一个声明。此
消除了许多示例。

There is an ambiguity in the grammar involving expression-statements and declarations: An expressionstatement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates many examples.

并提供以下示例:


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)的情况下,是 qualified-id c> , 是

Note: without the () then T ::D is a qualified-id in the case of T being a class, that is a covered in the grammar of 5.1 Primary expressions.

更新

提交了

Filed a gcc bug report.

gcc的回应是:

gcc's response is that:


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

Current G++ and EDG both treat it as the valid expression (int)::x

由于此回应暗示 clang 不正确(我不同意,),我提出了诽谤错误报告较旧的错误报告看起来类似,似乎不同意 gcc 响应。

Since this response implies clang is incorrect(I don't agree though), I filed a clang bug report and older bug report looks similar and seems to disagree with the gcc response.

更新2

响应 / code> Richard Smith同意这应该被视为一个声明,并说:

In response to the clang bug report Richard Smith agrees this should be treated as a declaration and says:


这并不意味着俚语不正确;其实,Clang是正确的
在这里,据我所见。 (我也向EDG发送了一个错误报告。)

That does not imply clang is incorrect; in fact, Clang is correct here, as far as I can see. (I've also sent a bug report to EDG.)

也就是说,我们应该给出一个正确的'你敲击一个烦人的解析,这里是如何
消除歧义错误。

That said, we should give a proper 'you hit a vexing parse, here's how to disambiguate' error in this case.

更新3

gcc 确认这是一个错误。

这篇关于是Type(:: x);有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆