Why can't I use the same variable as an inner loop does?

Published 18 May 04 02:59 PM

Q: Why can't I do the following:

namespace Bug

{

            class Class1

            {

                        [STAThread]

                        static void Main(string[] args)

                        {

                                    for(int i=0; i<100; i++)

                                    {

 

                                    }

 

                                    int i = 0;

                        }

            }

}

the compiler gives me an error on the “int i = 0;” part of the code.

A: This is correct behavior, and is covered in section 3.7 of the language spec. It says, “The scope of a local variable declared in a local-variable-declaration (8.5.1) is the block in the which the declaration occurs”.

The scope of i is therefore the entire Main() function, and that means that the use in the for loop is a re=use, and therefore is not allowed.

This behavior is inteded to make incorrect re-use of variable names (such as in a cut and paste) less likely.

[Author: Eric Gunnerson]

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Ryan Gregg said on May 18, 2004 3:17 PM:
This really isn't a big problem. In fact, it has saved myself and some others I know several times from screwing up the value of local variables by reusing them inside a loop.

Btw, the C# Team FAQ blog is great. I look forward to all sorts of new posts on my (current) favorite programming language.
# Justin Rogers said on May 18, 2004 3:42 PM:
Two uses of i:
child scope in the for loop
function local scope just after the for loop

Now, you say that the use inside of the for-loop is the re-use, since even though we declare i at the bottom of the method, it has scope for the entire method. I can live with that. However, you output an error saying that the second use (the function local) is a redefinition of i in the child scope.

So while function local variables have function scope, they don't have function visibility. I can't define a variable at the end of my function but make use of it in the beginning even though the definition at the end gives the variable function scope.

Intrinsically this makes a large amount of sense to parse variables in front to back order and only make them visible for areas of the function in which they are defined. However, you don't really know the flow of the method in advance. Take this rather contrived example that fails in the C# compiler:

namespace Bug {
class Class1 {
static void Main(string[] args) {
goto variable_definitions;
function:

for(i=0; i<100; i++) { }

goto end;

variable_definitions:
int i = 0;
goto function;

end:

return;
}
}
}

I'm guessing some of the same semantics that are at play here also prevent the re-use of local variable slots in for nested scope variables that have the same type.

http://weblogs.asp.net/justin_rogers/archive/2004/02/16/73627.aspx
# Dennis v/d Stelt said on May 19, 2004 10:40 AM:
Same goes for the switch statement.

swith (a)
{
case b:
for (int i = 1; i<=10; i++)
{
Console.WriteLine("Do this 10 times")
}
break;
case c:
for (int i = 1; i<=20; i++)
{
Console.WriteLine("Do this 20 times")
}
break;
case d:
Object myObject = new Object();
myObject.DoSomething();
break;
case e:
Object myObject = new Object();
myObject.DoSomethingElse();
break;
}

Doesn't work either... Kinda sucks, but I think it's for the best! :)

In case e, the variable is already declared, according to the compiler, in case d.
# Thomas Eyde said on May 23, 2004 1:41 AM:
I don't get it. The variable is not visible outside the for loop, how can it belong to the main block?

My intuition says 'i' also is a member of the for block. It is not visible outside of it, hence it can't be used, so reuse should be allowed.

There is simply not possible to use it incorrectly.
# Thomas Eyde said on May 23, 2004 1:56 AM:
<blush>
My mistake. The latter 'i' does of course belong to the main block. So it does make sense
</blush>
# martin said on July 6, 2004 6:16 PM:
namespace Bugx
{
Class Class1
{
[STAThread]
static void Main(string[] args)
{
for( int i=0; i<100; i++){
}
for( int i=0; i<100; i++){
//Why is right here?
}
{
//right here?
int i = 0;
}
int i =0 ; //why is error here?
}
}
}
# rin said on August 2, 2004 1:26 AM:
Believe you, support you, I believe that you are right! ! ! I will make great efforts to look like your study! ! !
# RebelGeekz said on December 28, 2004 4:54 AM:
[http://itpeixun.51.net/][http://aissl.51.net/][http://kukuxz003.freewebpage.org/][http://kukuxz001.51.net/][http://kukuxz003.51.net/][http://kukuxz005.51.net/][http://kukuxz002.51.net/][http://kukuxz004.freewebpage.org/][http://kukuxz007.51.net/][http://kukuxz001.freewebpage.org/][http://kukuxz006.51.net/][http://kukuxz002.freewebpage.org/][http://kukuxz004.51.net/][http://kukuxz008.51.net/][http://kukuxz009.51.net/][http://kukuxz005.freewebpage.org/][http://kukuxz006.freewebpage.org/][http://kukuxz007.freewebpage.org/][http://kukuxz009.freewebpage.org/]

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

This Blog

Syndication

Page view tracker