• <tfoot id='gMmI1'></tfoot>

      <small id='gMmI1'></small><noframes id='gMmI1'>

          <bdo id='gMmI1'></bdo><ul id='gMmI1'></ul>
        <legend id='gMmI1'><style id='gMmI1'><dir id='gMmI1'><q id='gMmI1'></q></dir></style></legend>
        <i id='gMmI1'><tr id='gMmI1'><dt id='gMmI1'><q id='gMmI1'><span id='gMmI1'><b id='gMmI1'><form id='gMmI1'><ins id='gMmI1'></ins><ul id='gMmI1'></ul><sub id='gMmI1'></sub></form><legend id='gMmI1'></legend><bdo id='gMmI1'><pre id='gMmI1'><center id='gMmI1'></center></pre></bdo></b><th id='gMmI1'></th></span></q></dt></tr></i><div id='gMmI1'><tfoot id='gMmI1'></tfoot><dl id='gMmI1'><fieldset id='gMmI1'></fieldset></dl></div>
      1. 是类型(::x);有效的?

        Is Type(::x); valid?(是类型(::x);有效的?)
          <legend id='gPeRV'><style id='gPeRV'><dir id='gPeRV'><q id='gPeRV'></q></dir></style></legend>
              <tbody id='gPeRV'></tbody>
            <i id='gPeRV'><tr id='gPeRV'><dt id='gPeRV'><q id='gPeRV'><span id='gPeRV'><b id='gPeRV'><form id='gPeRV'><ins id='gPeRV'></ins><ul id='gPeRV'></ul><sub id='gPeRV'></sub></form><legend id='gPeRV'></legend><bdo id='gPeRV'><pre id='gPeRV'><center id='gPeRV'></center></pre></bdo></b><th id='gPeRV'></th></span></q></dt></tr></i><div id='gPeRV'><tfoot id='gPeRV'></tfoot><dl id='gPeRV'><fieldset id='gPeRV'></fieldset></dl></div>

              <tfoot id='gPeRV'></tfoot>

              <small id='gPeRV'></small><noframes id='gPeRV'>

                • <bdo id='gPeRV'></bdo><ul id='gPeRV'></ul>

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

                  问题描述

                  虽然讨论Type(identifier); 语法以及它是如何声明的,我遇到了 Type(::x); 不适用于 Clang.我希望给定一个全局变量 x,它会将 ::x 视为一个表达式(::x + 2 有效)并强制转换::xType.但是,它会导致编译器错误.

                  这是一个简短的例子:

                  int x;int main() {int(::x);//不编译int(::x + 2);//编译}

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

                  <块引用>

                  错误:'x' 的定义或重新声明不能命名全局作用域

                  然而,GCC 4.9.0 编译得很好.此代码是否有效?

                  解决方案

                  据我所知,draft C++ 标准 部分 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 错误修复列表,但他们并没有声称这是一个完整的列表.

                  第二种情况是函数式显式类型转换,在5.2.3 部分有介绍 显式类型转换(函数式表示法) 内容如下:

                  <块引用>

                  简单类型说明符 (7.1.6.2) 或类型名称说明符 (14.6)后跟一个带括号的表达式列表构造一个值给定表达式列表的指定类型.如果表达式列表是一个单个表达式,类型转换表达式等价(在定义,如果在含义中定义)到相应的演员表表达式 (5.4).[...]

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

                  当一个语句被认为是声明或表达式的部分是6.8 歧义解决,它说:

                  <块引用>

                  涉及表达式语句的语法存在歧义和声明:具有函数风格的表达式语句显式类型转换 (5.2.3) 作为其最左边的子表达式可以是与第一个声明符开始的声明没有区别带有 (. 在这些情况下,该语句是一个声明. [ 注意:要消除歧义,可能需要检查整个陈述确定它是表达式语句还是声明.这消除了许多例子的歧义.

                  并提供以下示例:

                  <块引用>

                  T(a)->m = 7;//表达式语句T(a)++;//表达式语句T(a,5)<<c;//表达式语句T(*d)(int);//宣言T(e)[5];//宣言T(f) = { 1, 2 };//宣言T(*g)(双(3));//宣言

                  注意:没有 () 那么 T ::DTqualified-idcode> 是一个,它包含在5.1主要表达式的语法中.

                  更新

                  提交了 gcc 错误报告.

                  gcc 的回应是:

                  <块引用>

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

                  由于此回复暗示 clang 不正确(我不同意),我提交了一个 clang 错误报告 和 较旧的错误报告 看起来很相似,似乎不同意 gcc 响应.

                  更新 2

                  为了回应 clang 错误报告,Richard Smith 同意这应该被视为声明并说:

                  <块引用>

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

                  也就是说,我们应该给出一个正确的'你遇到了一个令人烦恼的解析,这就是方法在这种情况下消除'错误.

                  更新 3

                  gcc 确认是个bug.

                  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.

                  Here is a short example:

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

                  The compiler error given by Clang 3.5 is:

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

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

                  解决方案

                  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):

                  In a declaration T D where D has the form

                  ( D1 )

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

                  T D1

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

                  so:

                  int(::x);
                  

                  is equivalent to:

                  int ::x ;
                  

                  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.

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

                  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).[...]

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

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

                  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.

                  and provides the following 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
                  

                  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.

                  Update

                  Filed a gcc bug report.

                  gcc's response is that:

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

                  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.

                  Update 2

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

                  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.

                  Update 3

                  gcc confirms it is a bug.

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

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Difference between an inline function and static inline function(内联函数和静态内联函数的区别)
                  Compilation fails randomly: quot;cannot open program databasequot;(编译随机失败:“无法打开程序数据库)
                  Too many initializers error for a simple array in bcc32(bcc32 中的简单数组的初始值设定项过多错误)
                  No Member named stoi in namespace std(命名空间 std 中没有名为 stoi 的成员)
                  Error using a constexpr as a template parameter within the same class(在同一个类中使用 constexpr 作为模板参数时出错)
                  Validate an argument is ARRAY type in c/c++ pre processing macro on compile time(在编译时验证 c/c++ 预处理宏中的参数是否为 ARRAY 类型)
                    <bdo id='ToVnD'></bdo><ul id='ToVnD'></ul>

                      <i id='ToVnD'><tr id='ToVnD'><dt id='ToVnD'><q id='ToVnD'><span id='ToVnD'><b id='ToVnD'><form id='ToVnD'><ins id='ToVnD'></ins><ul id='ToVnD'></ul><sub id='ToVnD'></sub></form><legend id='ToVnD'></legend><bdo id='ToVnD'><pre id='ToVnD'><center id='ToVnD'></center></pre></bdo></b><th id='ToVnD'></th></span></q></dt></tr></i><div id='ToVnD'><tfoot id='ToVnD'></tfoot><dl id='ToVnD'><fieldset id='ToVnD'></fieldset></dl></div>
                        <tbody id='ToVnD'></tbody>

                    1. <small id='ToVnD'></small><noframes id='ToVnD'>

                        <legend id='ToVnD'><style id='ToVnD'><dir id='ToVnD'><q id='ToVnD'></q></dir></style></legend>
                      • <tfoot id='ToVnD'></tfoot>