8

在尝试了 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 !! 
} 

呵呵,为什么不一样?

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

4

2 回答 2

14

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

>>int x = 1;
>>{ int x = x; }  // garbage value of x

来自第:-3.3.1.1 节(C++ 标准草案)名称的声明点紧接在其完整声明符之后和其初始化程序(如果有)之前,除非如下所述。

int x = 12;
{ int x = x; }

这里; 'operator =' 是初始化器。你可以说'x'的声明点还没有达到,所以'x'的值是不确定的。

>>int const arr = 3;
>>{ int arr[arr]; } // i am told this is perfectly valid and declares an array of 3 ints !!

为什么?来自章节:-3.3.1.4(C++ 标准草案)非本地名称在隐藏它的本地名称的声明点之前保持可见。这里的声明点是在';' 特点。所以使用'arr'的早期可见值,即= 3。

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

const int e = 2;
{ enum { e = e }; } // enum e = 2

来自章节:-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
};

为什么?因为枚举数被导出到枚举的封闭范围。在上面的示例中,声明了枚举器 Spades、Clubs、Hearts 和 Diamonds。因为枚举器被导出到封闭范围,所以它们被认为具有全局范围。示例中的标识符已经在全局范围内定义。所以这是一个错误。

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

于 2009-09-02T07:29:53.187 回答
7

首先,在现实世界中你不应该使用这两者,因为它是令人困惑的,即使是几秒钟来理解这个细节也太浪费了。

放弃我的其余答案 - Abhay 已经做对了,而且更详细:)

于 2009-09-02T07:37:12.173 回答