C++:令人困惑的声明语义

8 c++ declaration semantics

在尝试了Perl和一点C之后,我正在尝试学习C++,并且我已经陷入了细节和陷阱.考虑一下: -

int x = 1;
{ 
  int x = x; // garbage value of x
}
int const arr = 3;
{ 
  int arr[arr]; // i am told this is perfectly valid and declares an array of 3 ints !! 
} 
Run Code Online (Sandbox Code Playgroud)

嗯,为什么区别?

澄清:使用相同的名称在一种情况下有效,在另一种情况下无效.

Abh*_*hay 14

欢迎来到C++的世界!对于您的问题,答案在于一个名为"声明点"的概念.

>>int x = 1;
>>{ int x = x; }  // garbage value of x
Run Code Online (Sandbox Code Playgroud)

来自章节:-3.3.1.1(C++标准草案)名称的声明点紧跟在其完整的声明符之后和初始化器之前(如果有的话),除非下面说明.

int x = 12;
{ int x = x; }
Run Code Online (Sandbox Code Playgroud)

这里; 'operator ='是初始化程序.你可以说'x'的声明点尚未达到,因此'x'的值是不确定的.

>>int const arr = 3;
>>{ int arr[arr]; } // i am told this is perfectly valid and declares an array of 3 ints !!
Run Code Online (Sandbox Code Playgroud)

为什么?来自章节:-3.3.1.4(C++标准草案)非本地名称在声明隐藏它的本地名称之前仍然可见.这里的声明点在';'处达到 字符.因此使用'arr'的早期可见值ie = 3.

此外,您可能希望知道以下内容有效: -

const int e = 2;
{ enum { e = e }; } // enum e = 2
Run Code Online (Sandbox Code Playgroud)

来自章节:-Chapter-3.3.1.4(C++标准草案): - 枚举器的声明点紧接在其枚举器定义之后.

但是,不要这样做

const int Spades = 1, Clubs = 2, Hearts = 3, Diamonds = 4;
enum Suits
{
  Spades = Spades,     // error
  Clubs,               // error
  Hearts,              // error
  Diamonds             // error
};
Run Code Online (Sandbox Code Playgroud)

为什么?因为枚举数被导出到枚举的封闭范围.在上面的例子中,宣布了调查员黑桃,俱乐部,心和钻石.因为枚举数被导出到封闭范围,所以它们被认为具有全局范围.示例中的标识符已在全局范围内定义.所以这是一个错误.

有关其他细节和陷阱(:-)),请参阅草案C++标准中的第3.3节"声明区域和范围",如果感兴趣,您可以从此处获取pdf (http://www.research.att) .com/~bs/SC22-N-4411.pdf).

  • 规则需要复杂的原因是C++声明符*是*复杂的.那里有很多功能,结合了大量的向后兼容性,没有从它的C历史中删除干净(这些东西没有被正式指定,像这样的边缘情况通常由编译器实现者决定),而你获得C++标准规则. (3认同)

Max*_*xVT 7

首先,在现实世界中你不应该使用它,因为它很混乱,甚至几秒钟来理解这个细节也太浪费了.

废弃我的其余答案 - Abhay已经把它弄好了,而且更详细:)