473,383 Members | 1,813 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Are C# scoping rules different from C++

Hi,

When I try and compile the a class containing the following method :

public void doSomething() {
for (int i=0; i<5; i++) {
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
int i = 23;
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}

I get the following errors :

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 02): A local variable
named 'i' cannot be declared in this scope because it would give a different
meaning to 'i', which is already used in a 'child' scope to denote something
else

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 02): The name 'i' does not
exist in the class or namespace 'ForestResearch.UnitTests.TestBaseEntities'

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 03): A local variable
named 'list' cannot be declared in this scope because it would give a
different meaning to 'list', which is already used in a 'child' scope to
denote something else

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 03): The name 'list' does
not exist in the class or namespace
'ForestResearch.UnitTests.TestBaseEntities'

The C# Language spec states :
a.. The scope of a local variable declared in a for-initializer of a for
statement (§8.8.3) is the for-initializer, the for-condition, the
for-iterator, and the contained statement of the for statement.
If the put the statements following the for statement in an anonymous block
like this then the compiler is happy :

public void doSomething() {
for (int i=0; i<5; i++) {
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
{
int i = 23;
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
}

Interestingly if I do the converse (i.e. put the for statement in an
anonymous block and DON'T put the statements following in an anonymous
block) then I get the same compiler errors!

I'm using Microsoft Visual Studio 2002.

Questions :

1. I would have thought that the scope of 'i' is the for initializer and for
statement so that this identifier could be used again as I have done above
in my first example ?

2. Likewise I would have thought that the scope of the variable 'list'
should just be the block in which it is declared and so could be used again
as I have done in my first example ?

3. Why does my second example produce no compiler errors ?
Thanks in advance,
Joel Gordon.
Nov 16 '05 #1
4 3494
C# scoping specifications try "intelligently" protecting developers from making mistakes of using a variable accidentally. Hence, the compiler is designed to produce an error when such a scoping is made.

The paranthesis prove that you are aware of the scoping and hence you're informing the compiler explicitly of your intentions.

However, this is a pretty lame feature of the compiler - maybe helps at times. But try doing something like this:

class CTest
{
public void foo()
{
int x = 4;
Console.WriteLine( x );
}

int x = -1;
}

The compiler will compile without a problem!
Nov 16 '05 #2
Apparently C# doesn't like variables with the same name in *nested* scopes.

kevin aubuchon

"Joel Gordon" <jo*********@forestresearch.co.nz> wrote in message
news:eE****************@TK2MSFTNGP11.phx.gbl...
Hi,

When I try and compile the a class containing the following method :

public void doSomething() {
for (int i=0; i<5; i++) {
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
int i = 23;
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}

I get the following errors :

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 02): A local variable
named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 02): The name 'i' does not exist in the class or namespace 'ForestResearch.UnitTests.TestBaseEntities'
D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 03): A local variable
named 'list' cannot be declared in this scope because it would give a
different meaning to 'list', which is already used in a 'child' scope to
denote something else

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 03): The name 'list' does not exist in the class or namespace
'ForestResearch.UnitTests.TestBaseEntities'

The C# Language spec states :
a.. The scope of a local variable declared in a for-initializer of a for
statement (§8.8.3) is the for-initializer, the for-condition, the
for-iterator, and the contained statement of the for statement.
If the put the statements following the for statement in an anonymous block like this then the compiler is happy :

public void doSomething() {
for (int i=0; i<5; i++) {
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
{
int i = 23;
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
}

Interestingly if I do the converse (i.e. put the for statement in an
anonymous block and DON'T put the statements following in an anonymous
block) then I get the same compiler errors!

I'm using Microsoft Visual Studio 2002.

Questions :

1. I would have thought that the scope of 'i' is the for initializer and for statement so that this identifier could be used again as I have done above
in my first example ?

2. Likewise I would have thought that the scope of the variable 'list'
should just be the block in which it is declared and so could be used again as I have done in my first example ?

3. Why does my second example produce no compiler errors ?
Thanks in advance,
Joel Gordon.

Nov 16 '05 #3
It's prohibited to declare the same variable name more than once within a
code block or any children of that block.

I have to agree, I find *your* understanding of how it should work more
intuitive, but that's the way it is, for better or for worse.

Your second example works because "i" for example exists in two different
code blocks that are not in a parent/child relationship -- they are what I
would term "peers". If you declared "i" outside both code blocks, at the
top level of the method, then you'd have the problem again because both peer
code blocks would themselves be children of the top-level scope, the method
itself.

In practice I usually find myself declaring variables I want to reuse at a
higher scope, e.g.,

public void doSomething() {
int i = 0;
IList list = null;

for (i = 0;i < 5;i++) {
list = new ArrayList();
Console.WriteLine(i / list.Count);
}

i = 23;
list = new ArrayList();
Console.WriteLine(i / list.Count);
}

The problem here is that if you don't assign values when you do the initial
declarations, the compiler often needlessly natters about uninitialized
variables. And of course this isn't as "safe". But methods should be of a
manageable size; if you start losing track of things it needs refactoring
anyway. So I think it's an acceptable trade-off.

--Bob

"Joel Gordon" <jo*********@forestresearch.co.nz> wrote in message
news:eE****************@TK2MSFTNGP11.phx.gbl...
Hi,

When I try and compile the a class containing the following method :

public void doSomething() {
for (int i=0; i<5; i++) {
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
int i = 23;
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}

I get the following errors :

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 02): A local variable
named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 02): The name 'i' does not exist in the class or namespace 'ForestResearch.UnitTests.TestBaseEntities'
D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 03): A local variable
named 'list' cannot be declared in this scope because it would give a
different meaning to 'list', which is already used in a 'child' scope to
denote something else

D:\Forecaster\TestForecaster\TestBaseEntities.cs(4 03): The name 'list' does not exist in the class or namespace
'ForestResearch.UnitTests.TestBaseEntities'

The C# Language spec states :
a.. The scope of a local variable declared in a for-initializer of a for
statement (§8.8.3) is the for-initializer, the for-condition, the
for-iterator, and the contained statement of the for statement.
If the put the statements following the for statement in an anonymous block like this then the compiler is happy :

public void doSomething() {
for (int i=0; i<5; i++) {
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
{
int i = 23;
IList list = new ArrayList();
Console.WriteLine( i / (list.Count) );
}
}

Interestingly if I do the converse (i.e. put the for statement in an
anonymous block and DON'T put the statements following in an anonymous
block) then I get the same compiler errors!

I'm using Microsoft Visual Studio 2002.

Questions :

1. I would have thought that the scope of 'i' is the for initializer and for statement so that this identifier could be used again as I have done above
in my first example ?

2. Likewise I would have thought that the scope of the variable 'list'
should just be the block in which it is declared and so could be used again as I have done in my first example ?

3. Why does my second example produce no compiler errors ?
Thanks in advance,
Joel Gordon.

Nov 16 '05 #4
Thanks for all the replies.

I now a wiser person :-)

Cheers,
Joel Gordon.
Nov 16 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: Michele Simionato | last post by:
I have read with interest the recent thread about closures. The funny thing is that the authors are arguing one against the other but I actually agree with all of them and I have a proposal that...
68
by: Marco Bubke | last post by:
Hi I have read some mail on the dev mailing list about PEP 318 and find the new Syntax really ugly. def foo(x, y): pass I call this foo(1, 2), this isn't really intuitive to me! Also I...
0
by: Eyal Lotem | last post by:
Python has a few issues many consider problems with regard to its variable namespacing. It seems that the local/global/builtins namespacing rules are ancient remnants of a different Python. ...
4
by: Frederick Grim | last post by:
okay so the code in question looks like: namespace util { template<typename C> inline void mmapw(C *& ptr, size_t length, int prot, int flags, int fd, off_t offset) { if((ptr =...
7
by: Charles Krug | last post by:
List: I've a module that's not doing what I expect. My guess is that I don't quite understand the scoping rules the way I should. I have an object that's costly to create. My thought was to...
9
by: NevilleDNZ | last post by:
Can anyone explain why "begin B: 123" prints, but 456 doesn't? $ /usr/bin/python2.3 x1x2.py begin A: Pre B: 123 456 begin B: 123 Traceback (most recent call last): File "x1x2.py", line 13,...
3
by: morris.slutsky | last post by:
So every now and then I like to mess around with hobby projects - I often end up trying to write an OpenGL video game. My last attempt aborted due to the difficulty of automating game elements and...
17
by: Chad | last post by:
The following question stems from Static vs Dynamic scoping article in wikipedia. http://en.wikipedia.org/wiki/Scope_(programming)#Static_versus_dynamic_scoping Using this sites example, if I...
2
by: Joshua Kugler | last post by:
I am trying to use lamdba to generate some functions, and it is not working the way I'd expect. The code is below, followed by the results I'm getting. More comments below that. patterns = (...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.