try...catch and local variables

P

Peter Duniho

Jon Skeet said:
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
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
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.
 
P

Peter Duniho

Jon Skeet said:
[...]
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
 
M

Marc Gravell

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
 
P

Peter Duniho

Marc Gravell said:
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
 
P

Peter Duniho

Peter Duniho said:
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.
 
J

Jon Skeet [C# MVP]

Peter said:
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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Variables and Try/Catch 14
try & catch 8
try { DataReader } catch { 22 } 9
try-catch question 5
Once again on try/catch, using and IO 7
Unassigned error in Catch 3
try...catch...inside loop 8
C# socket reconnect 3

Top