Reputation:

C++: Confusing declaration semantics

After trying my hand at Perl and a little bit of C, I am trying to learn C++ and already i am bogged down by the details and pitfalls. Consider this:-

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 !! 
} 

Huh, Why the difference ?

To Clarify: Use of the same name is valid in one case and invalid in another.

Upvotes: 8

Views: 479

Answers (2)

MaxVT
MaxVT

Reputation: 13234

First, in real world you should use neither because it is confusing, and even a few seconds for understanding this fine point is too much waste.

Scrap the rest of my answer - Abhay already got it right, and in far more detail :)

Upvotes: 7

Abhay
Abhay

Reputation: 7180

Welcome to the universe of C++! For your question, the answer lay in a concept called 'Point-of-declaration'.

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

From Section:-3.3.1.1 (C++ Standard Draft) The point of declaration for a name is immediately after its complete declarator and before its initializer (if any), except as noted below.

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

Here; the 'operator =' is the initializer. You can say that the point-of-declaration for 'x' is not yet reached, so the value of 'x' is indeterminate.

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

Why? From Section:-3.3.1.4 (C++ Standard Draft) A nonlocal name remains visible up to the point of declaration of the local name that hides it. Here the point of declaration is reached at ';' character. So the earlier visible value of 'arr' is used i.e. = 3.

Also, you may wish to know that the following is valid :-

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

From Section:-Chapter-3.3.1.4 (C++ Standard Draft):- The point of declaration for an enumerator is immediately after its enumerator-definition.

But, don't do this

const int Spades = 1, Clubs = 2, Hearts = 3, Diamonds = 4;
enum Suits
{
  Spades = Spades,     // error
  Clubs,               // error
  Hearts,              // error
  Diamonds             // error
};

Why? Because enumerators are exported to the enclosing scope of the enumeration. In the above example, the enumerators Spades, Clubs, Hearts, and Diamonds are declared. Because the enumerators are exported to the enclosing scope, they are considered to have global scope. The identifiers in the example are already defined in global scope. So its an error.

For additional details and pitfalls ( :-) ), read-up on section 3.3 'Declarative regions and scopes' from the Draft C++ Standard, if interested you can get hold of the pdf from here(http://www.research.att.com/~bs/SC22-N-4411.pdf).

Upvotes: 14

Related Questions