Why can't a duplicate variable name be declared in a nested local scope?

Based on this recent question , I do not understand the answer. It looks like you should be able to do something similar, as their areas do not overlap

static void Main() { { int i; } int i; } 

This code cannot compile with the following error:

A local variable named "i" cannot be declared in this scope because it will have a different meaning for "i", which is already used in the scope of "child" to mean something else

+47
c #
May 27 '11 at 18:44
source share
9 answers

I do not think that any of the answers so far has received the key line from the specification.

From section 8.5.1:

The scope of the local variable declared in the local variable declaration contains the block in which the declaration takes place . It is a mistake to refer to a local variable in the text position that precedes the local variable declarator of the local variable. Within a local variable, a compile-time error declares another local variable or constant with the same name.

(Emphasize mine.)

In other words, the scope for the โ€œlaterโ€ variable includes the portion of the block before the declaration, that is, includes the โ€œinnerโ€ block containing the โ€œearlierโ€ variable.

You cannot reference a later variable in a place earlier than your declaration - but still in scope.

+38
May 27 '11 at 19:02
source share

"The volume of a local or constant variable continues until the end of the current block. You cannot declare another local variable with the same name in the current block or in any nested blocks." C # 3.0 in a nutshell, http://www.amazon.com/3-0-Nutshell-Desktop-Reference-OReilly/dp/0596527578/

"The local declaration space of a block variable includes any nested blocks. Thus, it is impossible to declare a local variable with the same name as the local variable in the closing block inside the nested block." Area Variables, MSDN, http://msdn.microsoft.com/en-us/library/aa691107%28v=vs.71%29.aspx

On the side of the note, this is the exact opposite of the JavaScript and F # rules.

+8
May 27 '11 at 18:49
source share

From the C # language specification:

The local declaration space of a variable block includes any nested blocks. Thus, inside a nested block, it is not possible to declare a local variable with the same name as the local variable in the closing block.

Essentially, this is not allowed, because in C # their areas really overlap.

edit: just for clarification, the C # scope is allowed at the block level, not line by line. Therefore, although it is true that you cannot refer to a variable in the code that precedes its declaration, it is also true that its scope completely returns to the beginning of the block.

+6
May 27 '11 at 18:56
source share

This was a rule in C # from the first version.

Resolving matching areas will only lead to confusion (of programmers, not the compiler).

So it was banned on purpose.

+3
May 27 '11 at 18:51
source share

This is not a matter of overlapping areas. In C #, a simple name cannot mean more than one object in the block where it was declared. In your example, the name i means two different things inside the same external block.

In other words, you should be able to move the variable declaration anywhere in the block where it was declared without causing areas to overlap. By changing your example to:

 static void Main() { int i; { int i; } } 

will lead to overlapping areas of various variables i , your example is illegal.

+2
May 27 '11 at 18:50
source share

For C #, ISO 23270 (Information Technology - Programming Languages โ€‹โ€‹- C #), & sect; 10.3 (Declaration):

Each block, switch block, for-statement, foreach-statement or using-statement creates a declaration space for local variables and local constants called a declaration space of a local variable . Names entered into this declaration space through local declaration variables and local constants.

If the block is the instance body of a constructor, method or statement, or get or set accessor to declare an indexer, the parameters declared in such an declaration are members of the local space of the declaration of variable blocks.

If the block is the body of a general method, the type parameters declared in such a declaration are members of the local declaration space of variable blocks.

This is an error for two members of the local space of variable variables with the same name. This is a mistake for the local variable declaration space and nested local variables the variable declaration space to contain elements with the same name.

[Note: Thus, it is not possible to declare a local variable or constant with the same name as a local variable or constant in a closed block inside a nested block. It is possible that two nested blocks contain elements of the same name if neither of the blocks contains the other. end note]

So,

 public void foobar() { if ( foo() ) { int i = 0 ; ... } if ( bar() ) { int i = 0 ; ... } return ; } 

is legal but

 public void foobar() { int i = 0 ; if ( foo() ) { int i = 0 ; ... } ... return ; } 

not legal. Personally, I find this limitation quite annoying. I see how the compiler warning about overlapping areas, but a compilation error? Too many belts and suspenders, IMHO. I could see the virtue of the compiler and / or pragma option, though (perhaps -pedantic / -practical , #pragma pedantic vs #pragma practical , B^) ).

+2
May 27 '11 at 19:13
source share

I just compiled this in GCC for both C and C ++. I did not receive an error message, so it looks like syntax.

Your question is marked as .net and c. Should it be marked as C #? This language may have different rules than C.

+1
May 27 '11 at 18:49
source share

In C, you need to place all variable declarations at the very beginning of the block. They should arrive immediately after opening { before any other instructions in this block.

So what can you do to compile this:

 static void Main() { { int i; } { int i; } } 
+1
May 27 '11 at 18:49
source share

Here is your answer from the MSDN.NET Documentation :

... The local declaration space of a variable block includes any nested blocks. Thus, inside a nested block, it is not possible to declare a local variable with the same name as the local variable in the closing block.

0
May 27 '11 at 19:07
source share



All Articles