By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,677 Members | 1,094 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,677 IT Pros & Developers. It's quick & easy.

try...catch and local variables

P: n/a
I'm getting frustrated with using try...catch with local variables:

The code below wont compile in .NET 1.1: I get the following error: "Use of
unassigned local variable 'oProcessFileReader' "

Is there a way around this error?

<code>
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}

</code>
--
Thanks
Rick Hodder
Nov 21 '06 #1
Share this Question
Share on Google+
28 Replies


P: n/a
StreamReader oProcessFileReader=null;

Now it's not unassigned.

Peter
--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"RickHodder" wrote:
I'm getting frustrated with using try...catch with local variables:

The code below wont compile in .NET 1.1: I get the following error: "Use of
unassigned local variable 'oProcessFileReader' "

Is there a way around this error?

<code>
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}

</code>
--
Thanks
Rick Hodder
Nov 21 '06 #2

P: n/a
I'm getting frustrated with using try...catch with local variables:
>
The code below wont compile in .NET 1.1: I get the following error:
"Use of unassigned local variable 'oProcessFileReader' "

Is there a way around this error?
Set oProcessFileReader to null in your catch block.

Best Regards,
Dustin Campbell
Developer Express Inc.
Nov 21 '06 #3

P: n/a
Thanks Peter!

BTW, I really enjoy your blog.
--
Rick Hodder
"Peter Bromberg [C# MVP]" wrote:
StreamReader oProcessFileReader=null;

Now it's not unassigned.

Peter
--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"RickHodder" wrote:
I'm getting frustrated with using try...catch with local variables:

The code below wont compile in .NET 1.1: I get the following error: "Use of
unassigned local variable 'oProcessFileReader' "

Is there a way around this error?

<code>
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}

</code>
--
Thanks
Rick Hodder
Nov 21 '06 #4

P: n/a


"RickHodder" <Ri********@discussions.microsoft.comwrote in message
news:F0**********************************@microsof t.com...
I'm getting frustrated with using try...catch with local variables:

The code below wont compile in .NET 1.1: I get the following error: "Use
of
unassigned local variable 'oProcessFileReader' "

Is there a way around this error?

<code>
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}

</code>
--
Thanks
Rick Hodder
By just looking at the code and error, I see you are in fact not assigning
oProcessFileReader before using it. Even though you are checking for null,
the compiler isn't smart enough to notice and it results in the error you
are getting. What you can do is simply modify your declaration to read:

StreamReader oProcessFileReader = null;

and it should compile nicely (unless there are other errors in your code
that I'm over-looking.

Note: This is simply a compiler error and I'm not sure if you can turn off
this functionality. It exists to prevent you from doing something more
like:

StreamReader reader;
reader.ReadLine();

Which is obviously bad, so the compiler warns/throws a tantrum when you try
to do something that even remotely resembles this...

HTH,
Mythran
Nov 21 '06 #5

P: n/a
Mythran wrote:
....
Note: This is simply a compiler error and I'm not sure if you can turn
off this functionality. It exists to prevent you from doing something
more like:

StreamReader reader;
reader.ReadLine();

Which is obviously bad, so the compiler warns/throws a tantrum when you
try to do something that even remotely resembles this...
Do you mean that |reader| in your example is null? I am not sure
if memory for local variable declarations is primed with zeros. Is it
somewhere in the language specifications?
Nov 21 '06 #6

P: n/a
I am not sure if memory for local variable
declarations is primed with zeros. Is it
somewhere in the language specifications?
ECMA-334, 12 "A variable shall be definitely assigned (12.3) before its
value can be obtained."

So within the language, it is irrelevant (an implementation detail) whether
the variable is zero'd - as you cannot legally look to see. The CLR may
behave differently, but since this is a C# NG...

Marc
Nov 21 '06 #7

P: n/a
Marc Gravell wrote:
>I am not sure if memory for local variable
declarations is primed with zeros. Is it
somewhere in the language specifications?

ECMA-334, 12 "A variable shall be definitely assigned (12.3) before its
value can be obtained."

So within the language, it is irrelevant (an implementation detail) whether
the variable is zero'd - as you cannot legally look to see. The CLR may
behave differently, but since this is a C# NG...
Then, this is not a compiler error, contrary to what was suggested. Thanks.
Nov 21 '06 #8

P: n/a
Another way to write your code would be to use the "using" statement. It is
basically under the hood a try/finally statement which calls the Dispose
method on an object that implement IDisposable. If you want your catch
statement you will have to explicitly put that inside the using statment. So
your code:
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}
would become (without the catch statement):

private void Test(string sFileName)
{
using(StreamReader oProcessFileReader = File.OpenText(sFileName))
{
//use the oProcessFileReader
}

//here the stream has been disposed.
}

So even if an exception is thrown the resources are cleaned up, like in your
code, but with less typing :-).

Mark.
--
http://www.markdawson.org
"RickHodder" wrote:
I'm getting frustrated with using try...catch with local variables:

The code below wont compile in .NET 1.1: I get the following error: "Use of
unassigned local variable 'oProcessFileReader' "

Is there a way around this error?

<code>
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}

</code>
--
Thanks
Rick Hodder
Nov 21 '06 #9

P: n/a


"Sericinus hunter" <se*****@flash.netwrote in message
news:#T**************@TK2MSFTNGP02.phx.gbl...
Marc Gravell wrote:
>>I am not sure if memory for local variable
declarations is primed with zeros. Is it
somewhere in the language specifications?

ECMA-334, 12 "A variable shall be definitely assigned (12.3) before its
value can be obtained."

So within the language, it is irrelevant (an implementation detail)
whether the variable is zero'd - as you cannot legally look to see. The
CLR may behave differently, but since this is a C# NG...

Then, this is not a compiler error, contrary to what was suggested.
Thanks.
My apologies, it should read, "this is a compile* error" not compiler and
disregard the "I'm not sure if you can turn off this functionality", cause
obviously, you can't...

:)

HTH,
Mythran
Nov 21 '06 #10

P: n/a
>I'm getting frustrated with using try...catch with local variables:
>>
The code below wont compile in .NET 1.1: I get the following error:
"Use of unassigned local variable 'oProcessFileReader' "

Is there a way around this error?
Set oProcessFileReader to null in your catch block.
Sorry, I must have been out to lunch when I wrote. Initialize oProcessFileReader
to null when you declare it.

Best Regards,
Dustin Campbell
Developer Express Inc.
Nov 21 '06 #11

P: n/a
Another way to write your code would be to use the "using" statement.
It is basically under the hood a try/finally statement which calls the
Dispose method on an object that implement IDisposable. If you want
your catch statement you will have to explicitly put that inside the
using statment. So your code:
>private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}
would become (without the catch statement):

private void Test(string sFileName)
{
using(StreamReader oProcessFileReader = File.OpenText(sFileName))
{
//use the oProcessFileReader
}
//here the stream has been disposed.
}
So even if an exception is thrown the resources are cleaned up, like
in your code, but with less typing :-).
Unfortunately, a using statement doesn't actually protect the code that was
protected before. It will compile to this:

StreamReader oProcessFileReader = File.OpenText(sFileName);
try
{
// use the oProcessFileReader
}
finally
{
if (oProcessFileReader != null)
((IDisposable)oProcessFileReader).Dispose();
}

So, if an exception is raised by File.OpenText(), the call stack will immediately
unwind and the try/finally code doesn't ever execute. IOW, the code that
you presented doesn't actually do the same thing. I suppose that you *could*
do this:

private void Test(string sFileName)
{
try
{
using (StreamReader oProcessFileReader = File.OpenText(sFileName))
{
//use the oProcessFileReader
}

//here the stream has been disposed.
}
catch (Exception e)
{
MessageBox.Show("Error: " + e.Message);
}
}

But, now the scope for try/catch is pretty different--it will also be catching
any exceptions thrown by code other than File.OpenText.

I don't think there's anyway to precisely re-write the original code with
a using statement.

Best Regards,
Dustin Campbell
Developer Express Inc.
Nov 21 '06 #12

P: n/a
You're welcome, thanks for the compliment. Isn't it fun to see how 10 people
all say the same thing!
Peter
--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"RickHodder" wrote:
Thanks Peter!

BTW, I really enjoy your blog.
--
Rick Hodder
"Peter Bromberg [C# MVP]" wrote:
StreamReader oProcessFileReader=null;

Now it's not unassigned.

Peter
--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"RickHodder" wrote:
I'm getting frustrated with using try...catch with local variables:
>
The code below wont compile in .NET 1.1: I get the following error: "Use of
unassigned local variable 'oProcessFileReader' "
>
Is there a way around this error?
>
<code>
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}
>
</code>
>
>
--
Thanks
Rick Hodder
Nov 21 '06 #13

P: n/a
You are correct, I should have looked more closely at the OP. Note to self,
do not post when running out the door :-)
Unfortunately, a using statement doesn't actually protect the code that was
protected before. It will compile to this:

StreamReader oProcessFileReader = File.OpenText(sFileName);
try
{
// use the oProcessFileReader
}
finally
{
if (oProcessFileReader != null)
((IDisposable)oProcessFileReader).Dispose();
}
Also there are two extra braces that get compiled by the using statement to
limit the scope the of the local variable:

{
StreamReader oProcessFileReader = File.OpenText(sFileName);
try
{
// use the oProcessFileReader
}
finally
{
if (oProcessFileReader != null)
((IDisposable)oProcessFileReader).Dispose();
}
}

Mark.
--
http://www.markdawson.org
"Dustin Campbell" wrote:
Another way to write your code would be to use the "using" statement.
It is basically under the hood a try/finally statement which calls the
Dispose method on an object that implement IDisposable. If you want
your catch statement you will have to explicitly put that inside the
using statment. So your code:
private void Test(string sFileName)
{
StreamReader oProcessFileReader;
try
{
oProcessFileReader = File.OpenText(sFileName);
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
}
would become (without the catch statement):

private void Test(string sFileName)
{
using(StreamReader oProcessFileReader = File.OpenText(sFileName))
{
//use the oProcessFileReader
}
//here the stream has been disposed.
}
So even if an exception is thrown the resources are cleaned up, like
in your code, but with less typing :-).

Unfortunately, a using statement doesn't actually protect the code that was
protected before. It will compile to this:

StreamReader oProcessFileReader = File.OpenText(sFileName);
try
{
// use the oProcessFileReader
}
finally
{
if (oProcessFileReader != null)
((IDisposable)oProcessFileReader).Dispose();
}

So, if an exception is raised by File.OpenText(), the call stack will immediately
unwind and the try/finally code doesn't ever execute. IOW, the code that
you presented doesn't actually do the same thing. I suppose that you *could*
do this:

private void Test(string sFileName)
{
try
{
using (StreamReader oProcessFileReader = File.OpenText(sFileName))
{
//use the oProcessFileReader
}

//here the stream has been disposed.
}
catch (Exception e)
{
MessageBox.Show("Error: " + e.Message);
}
}

But, now the scope for try/catch is pretty different--it will also be catching
any exceptions thrown by code other than File.OpenText.

I don't think there's anyway to precisely re-write the original code with
a using statement.

Best Regards,
Dustin Campbell
Developer Express Inc.
Nov 21 '06 #14

P: n/a
"Mythran" <ki********@hotmail.comwrote in message
news:uZ**************@TK2MSFTNGP02.phx.gbl...
By just looking at the code and error, I see you are in fact not assigning
oProcessFileReader before using it. Even though you are checking for
null, the compiler isn't smart enough to notice and it results in the
error you are getting.
The compiler does notice that he's checking for null. The problem is that
he's not allowed to check for null until he's set the variable to null. He
really does have an uninitialized variable bug in his code.
[...]
Note: This is simply a compiler error and I'm not sure if you can turn
off this functionality. It exists to prevent you from doing something
more like:

StreamReader reader;
reader.ReadLine();

Which is obviously bad, so the compiler warns/throws a tantrum when you
try to do something that even remotely resembles this...
In this particular case, there *is* a code path that can result in the local
variable being accessed before being initialized, without initialization in
the declaration. Initializing the local variable is indeed the correct
solution to the error, and is also correct relative to the rest of the code
that was posted.

However, unfortunately the compiler sometimes also incorrectly complains
that the variable is uninitialized, even when all code paths *do* initialize
the variable before it's accessed.

IMHO, this is a serious compiler bug, because the only way to get rid of the
error is to put in a "dummy" initialization (such as setting the variable to
null), which consequentially will hide any true "uninitialized variable"
errors in the code.

In other words, with the compiler in the state in which it is now, there are
actually situations in which the compiler forces the programmer to write
code that is *more* likely to contain the bug that the error is trying to
help avoid. I'd find the irony very entertaining, if it weren't for the
fact that there's a serious code quality issue related to it. :)

Pete
Nov 21 '06 #15

P: n/a
Hi Dustin,

This is just for the fun of it, but I think your code:

try
{
using (StreamReader oProcessFileReader = File.OpenText(sFileName))
{ //use the oProcessFileReader
}

//here the stream has been disposed.
}
catch (Exception e)
{
MessageBox.Show("Error: " + e.Message);
}

is very similar in functionality to the original code. (with some scope
issues aside, because oProcessFileReader is not accessible now outside
the using block)
>But, now the scope for try/catch is pretty different--it will also be
catching any exceptions thrown by code other than File.OpenText.
On the original code, as it was inside a try/catch/finally block (and I
am still not sure what try/catch/finally blocks are useful for), if he
wanted to do anything with the stream, it would also catch those
exceptions, as your code does:

StreamReader oProcessFileReader = null;
try
{
oProcessFileReader = File.OpenText(sFileName);
//Do whatever you want to do with the stream here.
//Note that an exception here will be processed on the
//catch statement.
}
catch (Exception e)
{
MessageBox.Show("Error: "+e.Message);
}
finally
{
if(oProcessFileReader!=null)
oProcessFileReader.Close();
}
Regards,
Adrian.
Nov 21 '06 #16

P: n/a


"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
"Mythran" <ki********@hotmail.comwrote in message
news:uZ**************@TK2MSFTNGP02.phx.gbl...
>By just looking at the code and error, I see you are in fact not
assigning oProcessFileReader before using it. Even though you are
checking for null, the compiler isn't smart enough to notice and it
results in the error you are getting.

The compiler does notice that he's checking for null. The problem is that
he's not allowed to check for null until he's set the variable to null.
He really does have an uninitialized variable bug in his code.
>[...]
Note: This is simply a compiler error and I'm not sure if you can turn
off this functionality. It exists to prevent you from doing something
more like:

StreamReader reader;
reader.ReadLine();

Which is obviously bad, so the compiler warns/throws a tantrum when you
try to do something that even remotely resembles this...

In this particular case, there *is* a code path that can result in the
local variable being accessed before being initialized, without
initialization in the declaration. Initializing the local variable is
indeed the correct solution to the error, and is also correct relative to
the rest of the code that was posted.

However, unfortunately the compiler sometimes also incorrectly complains
that the variable is uninitialized, even when all code paths *do*
initialize the variable before it's accessed.

IMHO, this is a serious compiler bug, because the only way to get rid of
the error is to put in a "dummy" initialization (such as setting the
variable to null), which consequentially will hide any true "uninitialized
variable" errors in the code.

In other words, with the compiler in the state in which it is now, there
are actually situations in which the compiler forces the programmer to
write code that is *more* likely to contain the bug that the error is
trying to help avoid. I'd find the irony very entertaining, if it weren't
for the fact that there's a serious code quality issue related to it. :)

Pete
Yes yes, what I was thinking and what I typed were two diff things...

The compiler/framework isn't smart enough to see that it's just checking to
see that it's null...not really "smart enough", but wasn't written to work
that way :)

I wonder, and it's not tested...

StreamReader sr;
if (true) { sr = ... }
if (sr == null) { ... }

I wonder if the compiler/framework will barf on that too? :) Most
likely...

Maybe
HTH,
Mythran
Nov 22 '06 #17

P: n/a
"Mythran" <ki********@hotmail.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Yes yes, what I was thinking and what I typed were two diff things...
Is that still happening. :)
The compiler/framework isn't smart enough to see that it's just checking
to see that it's null
Checking to see that a variable is null is *accessing* that variable. If
the variable has not been initialized, then checking for null (or any other
value) is illegal.

This isn't an issue of "smart enough". The error in this case is valid and
correct. The code *is* actually buggy, as the variable is being used at a
point in time at which it's undefined.
...not really "smart enough", but wasn't written to work that way :)
In this particular example, the compiler is doing exactly what it's supposed
to.
I wonder, and it's not tested...

StreamReader sr;
if (true) { sr = ... }
if (sr == null) { ... }

I wonder if the compiler/framework will barf on that too? :) Most
likely...
That is more like the compiler bug I was talking about. I haven't tried
that exact construct, but I have written code where it is provable that the
variable *is* initialized prior to access, and yet the compiler complains
that it isn't. In these cases (such as your example, and the other examples
I've seen), adding the initialization required to get the compiler to stop
complaining can actually result in what is effectively an uninitialized
value bug, because the otherwise-unnecessary initialization hides any other
problems with initialization.

Pete
Nov 22 '06 #18

P: n/a
On Tue, 21 Nov 2006 10:23:02 -0800, Peter Bromberg [C# MVP]
<pb*******@yahoo.nospammin.comwrote:
>You're welcome, thanks for the compliment. Isn't it fun to see how 10 people
all say the same thing!
Peter
Amusing... (Your second sentence and all the answers) ;o)

Brevity is next to godliness....

Good luck with your project,

Otis Mukinfus
http://www.arltex.com
http://www.tomchilders.com
Nov 22 '06 #19

P: n/a
Peter Duniho <Np*********@NnOwSlPiAnMk.comwrote:

<snip>
I wonder if the compiler/framework will barf on that too? :) Most
likely...

That is more like the compiler bug I was talking about. I haven't tried
that exact construct, but I have written code where it is provable that the
variable *is* initialized prior to access, and yet the compiler complains
that it isn't. In these cases (such as your example, and the other examples
I've seen), adding the initialization required to get the compiler to stop
complaining can actually result in what is effectively an uninitialized
value bug, because the otherwise-unnecessary initialization hides any other
problems with initialization.
It's not a compiler bug. The compiler is working exactly to the
language specification, as it should do.

Now, if you want to complain that the language specification is
"wrong" - the specification is already fairly complicated in terms of
working out precisely when a variable is definitely assigned. I believe
it is much better to make a language slightly "dumber" but simpler to
reason about (i.e. simpler to make sure the compiler is correct,
simpler to make sure the specification doesn't let some oddities
through etc) than to try to make it incredibly smart.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 22 '06 #20

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
It's not a compiler bug. The compiler is working exactly to the
language specification, as it should do.
I don't have a copy of the language specification. Would you please quote
the part you're referencing, where the language specification says that even
if a statement is reachable only by code paths that initialize the variable,
the compiler should still emit an "uninitialized variable" error.

Thanks,
Pete
Nov 22 '06 #21

P: n/a
"Otis Mukinfus" <ph***@emailaddress.comwrote in message
news:j4********************************@4ax.com...
Brevity is next to godliness....
But only in a really bad dictionary... ;-)
Nov 22 '06 #22

P: n/a
Peter Duniho <Np*********@NnOwSlPiAnMk.comwrote:
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
It's not a compiler bug. The compiler is working exactly to the
language specification, as it should do.

I don't have a copy of the language specification. Would you please quote
the part you're referencing, where the language specification says that even
if a statement is reachable only by code paths that initialize the variable,
the compiler should still emit an "uninitialized variable" error.
From the C# 1.1 ECMA spec:

http://www.jaggersoft.com/csharp_standard/12.3.htm
and the pages following (click on the arrows on the right)

(I don't have a public link to a 2.0 spec handy.)

Those rules define the whether or not something is definitely assigned.
They don't say anything about things which the compiler *could* reason
about, such as:

string x;
for (int i=0; i < 10; i++)
{
// 0 < 10 so this will always be executed exactly
// once
x = "value";
}
Console.WriteLine (x);

and

string x;
if (true)
{
// This will definitely be executed
x = "value";
}
Console.WriteLine (x);

However, there *is* enough reasoning (because it has nothing to do with
the expressions within the statements) for this to be okay:

string x;
if (something)
{
x = "value";
}
else
{
x = "othervalue";
}
Console.WriteLine (x);
http://www.jaggersoft.com/csharp_standard/12.htm states that a variable
must be definitely assigned before its value can be obtained.

Any compiler which *did* allow either of the first two snippets above
to be compiled without error would be violating the spec.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 22 '06 #23

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
[...]
Any compiler which *did* allow either of the first two snippets above
to be compiled without error would be violating the spec.
I don't understand why that is the case. The page you referred me to simply
says "a variable is said to be definitely assigned if the compiler can
prove, by static flow analysis, that the variable has been automatically
initialized or has been the target of at least one assignment".

Since it is possible by static flow analysis (that is, by analyzing the flow
of execution in a non-runtime situation) to show that both of the examples
you mention will definitely assign the variable, why is the variable still
considered unassigned?

Pete
Nov 22 '06 #24

P: n/a
It does spell out the official rules in great depth; 12.3.3.9 states
that "for" is treated as "while"; "while" is described in 12.3.3.7:
http://www.jaggersoft.com/csharp_standard/12.3.3.7.htm

This basically gives a few rules about what happens if the loop test
(typically e.g. "i<10" in "for") definitely assigns a variable, but
says nothing about the body. So that is what any compliant compiler
should do...

Marc

Nov 23 '06 #25

P: n/a
"Marc Gravell" <ma**********@gmail.comwrote in message
news:11**********************@m7g2000cwm.googlegro ups.com...
It does spell out the official rules in great depth; 12.3.3.9 states
that "for" is treated as "while"; "while" is described in 12.3.3.7:
http://www.jaggersoft.com/csharp_standard/12.3.3.7.htm

This basically gives a few rules about what happens if the loop test
(typically e.g. "i<10" in "for") definitely assigns a variable, but
says nothing about the body. So that is what any compliant compiler
should do...
Well, I will admit that I have no special insight into the intent of the
writers of the specification. However, my interpretation is that the
specification "says nothing about the body" because the body is itself a
statement, and the rules for that statement would be described elsewhere,
depending on the form it takes.

It's the standard recursive grammar sort of thing.

And in particular, static analysis can show in that situation that the body
statement *is* reached, and *does* initialize the variable.

So, I still don't see anything in the specification that says that even when
a statement is only reachable by code paths that initialize a variable, the
compiler should emit an "uninitialized variable" error.

Pete
Nov 23 '06 #26

P: n/a
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:12*************@corp.supernews.com...
And in particular, static analysis can show in that situation that the
body statement *is* reached, and *does* initialize the variable.
Clarification:

"is *always* reached". That is, there is no code path that avoids the body
statement.
Nov 23 '06 #27

P: n/a
Peter Duniho wrote:
Well, I will admit that I have no special insight into the intent of the
writers of the specification. However, my interpretation is that the
specification "says nothing about the body" because the body is itself a
statement, and the rules for that statement would be described elsewhere,
depending on the form it takes.
The rules for definite assignment are all laid out under the section I
pointed you at - but they're not all on one page. That's why I
explained that you should use the arrows on the right of the page to
see the rest of the details.

<snip>
So, I still don't see anything in the specification that says that even when
a statement is only reachable by code paths that initialize a variable, the
compiler should emit an "uninitialized variable" error.
I have to admit to a mistake earlier - section 15.1 of the spec is
relevant here:
http://www.jaggersoft.com/csharp_standard/15.1.htm

In particular:

int x;
if (true)
{
x=0;
}
Console.WriteLine (x);

*is* valid, because the if expression is a *constant* one. The
following is invalid, because the compiler doesn't do any reasoning
about possible values of variables:
int x;
bool y = true;
if (y)
{
x=0;
}
Console.WriteLine (x);

In other words, the compiler does some *very primitive* checking. For
the "if" statement, the rules for reachability are described in
http://www.jaggersoft.com/csharp_standard/15.7.1.htm

Hope this clears things up - apologies for the previous inaccuracy
about the "if" example.

Jon

Nov 23 '06 #28

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Peter Duniho <Np*********@NnOwSlPiAnMk.comwrote:
>"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft. com...
It's not a compiler bug. The compiler is working exactly to the
language specification, as it should do.

I don't have a copy of the language specification. Would you please quote
the part you're referencing, where the language specification says that even
if a statement is reachable only by code paths that initialize the variable,
the compiler should still emit an "uninitialized variable" error.

From the C# 1.1 ECMA spec:

http://www.jaggersoft.com/csharp_standard/12.3.htm
and the pages following (click on the arrows on the right)

(I don't have a public link to a 2.0 spec handy.)
Here it is:
http://www.ecma-international.org/pu...s/Ecma-334.htm
Willy.

Nov 23 '06 #29

This discussion thread is closed

Replies have been disabled for this discussion.