473,395 Members | 1,583 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,395 software developers and data experts.

self-confidence of compiler

fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.
Nevertheless, compler forces me to do the useless initialization. Do the
designers of 'clever' robots forsee any overcoming for the limitations they
impose?
May 7 '07 #1
49 2071
Your code does not guarantee that jobId will ever be assigned.

--
HTH,

Kevin Spencer
Microsoft MVP

Printing Components, Email Components,
FTP Client Classes, Enhanced Data Controls, much more.
DSI PrintManager, Miradyne Component Libraries:
http://www.miradyne.net

"valentin tihomirov" <no**************@yandex.ruwrote in message
news:OP*************@TK2MSFTNGP02.phx.gbl...
fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.
Nevertheless, compler forces me to do the useless initialization. Do the
designers of 'clever' robots forsee any overcoming for the limitations
they impose?

May 7 '07 #2
fDeleted = false;
uint jobId;
foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}
if (fDeleted)
writeln(jobId + " has completed");
Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized
jobId. Nevertheless, compler forces me to do the useless
initialization. Do the designers of 'clever' robots forsee any
overcoming for the limitations they impose?
What if "structures" is empty and the code within the foreach never runs?

Hans Kesting
May 7 '07 #3
"valentin tihomirov" <no**************@yandex.ruschrieb im Newsbeitrag
news:OP*************@TK2MSFTNGP02.phx.gbl...
fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.
Nevertheless, compler forces me to do the useless initialization. Do the
designers of 'clever' robots forsee any overcoming for the limitations
they impose?
Hi Valentin,

I'm not sure, what exactly is your concern here.
Surely, this is one of the seldom cases, where a variable can't be used
unassigned, but the compiler supposes it can. This doesn't seem to be a
secial problem of C#, but for any language, that prohibits the use of
unassigned variables. (Though maybe C# is the only one until now, I'm not
sure).

Why don't you initialize it to zero? performence considerations?

If you want a language, that allows the use of unassigned variables, you
will have to use another language.

Christof

PS You could try to use

unsafe {uint* p = &jobId;}

just before the loop. Probably the compiler will optimize this assignment
away.
May 7 '07 #4
"Kevin Spencer" <un**********@nothinks.comschrieb im Newsbeitrag
news:uS**************@TK2MSFTNGP05.phx.gbl...
Your code does not guarantee that jobId will ever be assigned.
Yes, but it guarantees, that jobId is not used unassigned (if it doesn't
occur further down in the code).

BTW The code surely isn't tested, as it was posted. The compiler wouldn't
allow the use of struct as a identifier.

Christof
------

snippet from OP:
>fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.

May 7 '07 #5
What if "structures" is empty and the code within the foreach never runs?
In this case boolean flag remais false and the id remains untouched !
May 7 '07 #6
This doesn't seem to be a secial problem of C#, but for any language, that
prohibits the use of unassigned variables. (Though maybe C# is the only
one until now, I'm not sure).
I just wanted to know about language designer discussions on the topic. I
like freedom and doing reasonable things.
If you want a language, that allows the use of unassigned variables, you
will have to use another language.

Where do you see that?

I DO NOT USE ANY UNINITIALIZED VARIABLES!!!

I have told that explicitly in the OP. I thought that people think a bit
wider than compiler and can understand that.

Are people formatted by Micro Soft?

In the beginning, you tell that I do not use uninitialized vars. Then, you
tell that this is not a problem of a language. You conclude that the ones
who do not want to use uninitialized vars (all the adequate people) need a
lang which allows using unitialized data! What a starling train of thought
to upside things down!
May 7 '07 #7
"valentin tihomirov" <no**************@yandex.ruschrieb im Newsbeitrag
news:ON**************@TK2MSFTNGP02.phx.gbl...
>This doesn't seem to be a secial problem of C#, but for any language,
that prohibits the use of unassigned variables. (Though maybe C# is the
only one until now, I'm not sure).

I just wanted to know about language designer discussions on the topic. I
like freedom and doing reasonable things.
<snip>
I have told that explicitly in the OP. I thought that people think a bit
wider than compiler and can understand that.
<snip>
In the beginning, you tell that I do not use uninitialized vars. Then, you
tell that this is not a problem of a language. You conclude that the ones
who do not want to use uninitialized vars (all the adequate people) need a
lang which allows using unitialized data! What a starling train of thought
to upside things down!
The problem is not, that you use an unassigned variable; the problem is that
the compiler can't recognize it.

The designers of C# decided (for good reasen) not to allow any use of an
unassigned variable. After that, they had to decide, by wich rules they test
it.
It is an infeasable problem to automatically detect all cases of use of
unassigned variables and all cases of variables wich will never be used
unassigned. So they had to make a cut somewhere.
That's why I said, this is a problem for any language, that prohibits the
use of unassigned variables. There always will be cases, where a variable is
defnitly assigned on any access, wich the language resp. the compiler will
detect as probably use of unassigned variable.

From another perspective: Think of a language the (by specification) assigns
every local variable with the default value of the type (like in VB.NET). An
optimizing compiler could try to eliminate any implicit initilization, where
it detects, that the implicit start value will never be used.
In this case, with code analogous to yours the compiler would still
implicitly initialize the variable, because it can't detect, that the
initial value will never be used.

Now, C# only enforces you, to explicitly initialize variable, wich the above
mentioned compiler would initialize implicitly.

I hope you understand this better.

Christof
May 7 '07 #8
valentin tihomirov wrote:
>This doesn't seem to be a secial problem of C#, but for any language, that
prohibits the use of unassigned variables. (Though maybe C# is the only
one until now, I'm not sure).

I just wanted to know about language designer discussions on the topic. I
like freedom and doing reasonable things.
>If you want a language, that allows the use of unassigned variables, you
will have to use another language.


Where do you see that?

I DO NOT USE ANY UNINITIALIZED VARIABLES!!!

I have told that explicitly in the OP. I thought that people think a bit
wider than compiler and can understand that.
Are you saying that you want the compiler to detect (in the general
case) whether a variable will be uninitialized? Spend a minute thinking
about why creating such a compiler isn't possible (hint: halting problem).

Alun Harford
May 7 '07 #9
Valentin,

While yes the jobId will never be accessed, it is beyond the compiler to
figure it out.

What you are looking for is static analysis of the code, something way
beyond (and usually very computationally intensive) what a compiler is
expected to do.

Short answer, you are right, it shouldn't give you grief about this,
unfortunately, the compiler would have to expend a severe amount of
processing power and time to figure this out.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"valentin tihomirov" <no**************@yandex.ruwrote in message
news:OP*************@TK2MSFTNGP02.phx.gbl...
fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.
Nevertheless, compler forces me to do the useless initialization. Do the
designers of 'clever' robots forsee any overcoming for the limitations
they impose?

May 7 '07 #10
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.comwrote:
While yes the jobId will never be accessed, it is beyond the compiler to
figure it out.

What you are looking for is static analysis of the code, something way
beyond (and usually very computationally intensive) what a compiler is
expected to do.

Short answer, you are right, it shouldn't give you grief about this,
unfortunately, the compiler would have to expend a severe amount of
processing power and time to figure this out.
Perhaps more importantly than the processing power (at least in my
view) - to specify the *exact* behaviour here, i.e. what the compiler
must be able to work out - would make the C# language specification
huge compared with its current form.

The rules for definite assignment are currently incredibly tedious, but
at least they're reasonably clear. Putting in a lot of static analysis
requirements would make it a lot harder to understand what we *should*
be able to expect, and to verify that a compiler did the right thing.

--
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
May 7 '07 #11
On May 7, 7:23 am, "valentin tihomirov" <no-spam-valen...@yandex.ru>
wrote:
This doesn't seem to be a secial problem of C#, but for any language, that
prohibits the use of unassigned variables. (Though maybe C# is the only
one until now, I'm not sure).

I just wanted to know about language designer discussions on the topic. I
like freedom and doing reasonable things.
OK... you like the freedom to make your own decisions. C#, however, is
a language for the masses, and tries to help programmers who may not
be as smart as you are, so that they don't make simple mistakes.

Yes, you have carefully constructed your code so that for all paths of
execution, no unassigned variable is ever used. However, you've done
it in such a clever way that the simple static analysis built into the
compiler can't tell that this is so.

A lesser programmer would try to do the same thing that you did and
screw it up. The compiler is trying to help that guy. Unfortunately,
this cramps your style. The fact is that there is no middle ground
here: either the compiler allows you to do what you want without
complaint, and lets (I would say) the majority of programmers make
elementary errors which cost time and money to find and fix, or it
insists on checking for uninitialized variables (among other things)
and puts some constraints on people like you and me. I don't see how
it would be possible to accommodate both types of programmers.

If you want a language that lets you do whatever you like while
imposing few, if any constraints, use C++. However, I should point out
that all of the freedom C++ gives you ends up biting large numbers of
people. That's why C++ didn't take the business world by storm (for
example): the language gives one so much freedom that it's dead easy
to write subtly incorrect code.

So, C# does a bit too much hand-holding. C++, IMHO, does far too
little. No matter where you put the balance point, somebody is going
to be unhappy with it.

May 7 '07 #12
On Mon, 07 May 2007 14:46:57 -0700, Bruce Wood <br*******@canada.com>
wrote:
OK... you like the freedom to make your own decisions. C#, however, is
a language for the masses, and tries to help programmers who may not
be as smart as you are, so that they don't make simple mistakes.
[...]
So, C# does a bit too much hand-holding. C++, IMHO, does far too
little. No matter where you put the balance point, somebody is going
to be unhappy with it.
IMHO, that's a poor argument in this situation. As I have pointed out in
the past, the current behavior actually *reduces* the effectiveness of
hand-holding. It forces the programmer to initialize a variable with a
value that may or may not be valid, and in a way that will hide any true
"this variable is used before it's initialized" bugs (at least at compile
time).

I defer to the claims that it would be impractical for the compiler to
correctly handle all cases, as well as to the claims that the language
specification specifically calls out the current behavior. While I'm not
entirely in agreement with those claims, they are more subjective and
harder to debate. But I don't find it supportable at all to claim that
the current behavior always ensures more bug-free code, or is even an
example of improved "hand-holding".

Pete
May 7 '07 #13
On May 7, 4:14 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Mon, 07 May 2007 14:46:57 -0700, Bruce Wood <brucew...@canada.com>
wrote:
OK... you like the freedom to make your own decisions. C#, however, is
a language for the masses, and tries to help programmers who may not
be as smart as you are, so that they don't make simple mistakes.
[...]
So, C# does a bit too much hand-holding. C++, IMHO, does far too
little. No matter where you put the balance point, somebody is going
to be unhappy with it.

IMHO, that's a poor argument in this situation. As I have pointed out in
the past, the current behavior actually *reduces* the effectiveness of
hand-holding. It forces the programmer to initialize a variable with a
value that may or may not be valid, and in a way that will hide any true
"this variable is used before it's initialized" bugs (at least at compile
time).

I defer to the claims that it would be impractical for the compiler to
correctly handle all cases, as well as to the claims that the language
specification specifically calls out the current behavior. While I'm not
entirely in agreement with those claims, they are more subjective and
harder to debate. But I don't find it supportable at all to claim that
the current behavior always ensures more bug-free code, or is even an
example of improved "hand-holding".
Well, all I can offer is my own experience. Even the much-maligned
"uninitialized variable" warning has helped me catch a few errors that
I would otherwise have let slip until I started testing, where they
would have been harder to catch.

However, you're right in one sense: this is probably like the Java
"checked exception" debate: it's too easy to simply do the wrong thing
in order to make the compiler shut up, rather than reorganizing the
code so that the warning is still useful but the code is now something
acceptable to the compiler. By this I mean the difference between
adding an "else" case to initialize the variable, rather than simply
setting it to zero upon declaration. That sort of thing.

As well, from my own experience, C++ newbies produce some of the
buggiest code I've ever seen. The language is so powerful, and
provides so little hand-holding that it's dead easy to make fatal
mistakes. With great power comes great responsibility, as it were.

May 7 '07 #14
On Mon, 07 May 2007 16:44:32 -0700, Bruce Wood <br*******@canada.com>
wrote:
Well, all I can offer is my own experience. Even the much-maligned
"uninitialized variable" warning has helped me catch a few errors that
I would otherwise have let slip until I started testing, where they
would have been harder to catch.
I apologize if I gave the impression that I was somehow not in favor of
having an "uninitialized variable" compiler error. That's not the case.
In fact, it's exactly because I think it's such a useful compile-time
error that it frustrates me when the compiler doesn't even pick up on
relatively simple cases where the variable *is* always initialized and I
have to do something arbitrary to make the compiler be quiet.

To be sure, I *like* having the compiler looking for uninitialized
variables. I just don't like it when the compiler is mistaken and
generates a false positive.
However, you're right in one sense: this is probably like the Java
"checked exception" debate: it's too easy to simply do the wrong thing
in order to make the compiler shut up, rather than reorganizing the
code so that the warning is still useful but the code is now something
acceptable to the compiler. By this I mean the difference between
adding an "else" case to initialize the variable, rather than simply
setting it to zero upon declaration. That sort of thing.
Well, that's part of my complaint. There are relatively simple examples
of the compiler complaining that involve only multiple paths, all of which
initialize a variable. Reorganizing the code doesn't really help. Either
the error remains, or the code is now reorganized in a less-desirable,
less-maintainable, less-clear way.

We're not talking about deeply nested, strangely-arranged loops, if()
statements, etc. here. We're talking about code that has just two
branches, both of which initialize the variable, and yet the compiler
complains.
As well, from my own experience, C++ newbies produce some of the
buggiest code I've ever seen. The language is so powerful, and
provides so little hand-holding that it's dead easy to make fatal
mistakes. With great power comes great responsibility, as it were.
I think C# represents great strides in improving the "idiot-proofness" of
the language. Again, this is one of the reasons this particular issue
bugs me. The compiler error as implemented not only fails to idiot-proof
the code, it tends to lead to code that is even more resistant to
idiot-proofing than usual.

Granted, there's always a better idiot. :) But I think the goals of C#
are commendable, and that's why I'm annoyed that it falls down in this one
particular situation.

Pete
May 8 '07 #15
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Well, that's part of my complaint. There are relatively simple examples
of the compiler complaining that involve only multiple paths, all of which
initialize a variable. Reorganizing the code doesn't really help. Either
the error remains, or the code is now reorganized in a less-desirable,
less-maintainable, less-clear way.

We're not talking about deeply nested, strangely-arranged loops, if()
statements, etc. here. We're talking about code that has just two
branches, both of which initialize the variable, and yet the compiler
complains.
Could you give an example? Here's one that *does* work:

using System;

class Program
{
static void Main(string[] args)
{
string x;

if (args.Length==0)
{
x = "None";
}
else
{
x = "Some";
}
Console.WriteLine (x);
}
}

Most examples which don't work (that I've seen) either involve for
loops or inter-dependency of two variables (if x is true then y is
definitely initialized).

I'm not doubting that you've run into more primitive issues, I'm just
interested in what they are :)

--
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
May 8 '07 #16
The rule: "Only initialized variables are allowed to be used" seems natural
and ultimately simple. The rules describing where you cut the analisys
should be extremely complex, I beleive.
May 8 '07 #17
Short answer, you are right, it shouldn't give you grief about this,
unfortunately, the compiler would have to expend a severe amount of
processing power and time to figure this out.
Does "severe" charactarize the halting problem? If it is true that the
problem is akin to the halting problem then infinite processing power is
needed, I suspect.
May 8 '07 #18
"valentin tihomirov" <no**************@yandex.ruschrieb im Newsbeitrag
news:%2***************@TK2MSFTNGP06.phx.gbl...
> Short answer, you are right, it shouldn't give you grief about this,
unfortunately, the compiler would have to expend a severe amount of
processing power and time to figure this out.

Does "severe" charactarize the halting problem? If it is true that the
problem is akin to the halting problem then infinite processing power is
needed, I suspect.
If the compiler should catch *all* cases of variables, that aren't accessed
uninitialized it would use up to infinite processing power and infinite
quantity of analyzing code.
May 8 '07 #19
IMHO, that's a poor argument in this situation. As I have pointed out in
the past, the current behavior actually *reduces* the effectiveness of
hand-holding. It forces the programmer to initialize a variable with a
value that may or may not be valid, and in a way that will hide any true
"this variable is used before it's initialized" bugs (at least at compile
time).
Thank you for this remarkable point. The garbage-initialization effectively
turns the protection off. Intuitively, I felt strange when recommended to
stop compiler protection for the reason the compiler is so good to protect
me. I become irritated when asked to produce absurd things, even as small as
garbage-initializer. Everybody should keep in mind that absolutely every
action consumes energy and other resourses.
May 8 '07 #20
If the compiler should catch *all* cases of variables, that aren't
accessed
uninitialized it would use up to infinite processing power and infinite
quantity of analyzing code.
Are you sure about infinite program size? If I remember Turing Machines
correctly, these most powerful computers have FSM (finite) controller. This
is infinite data storage, which they feature.
May 8 '07 #21
On Mon, 07 May 2007 22:58:27 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
Could you give an example? Here's one that *does* work:
Sure. Here's the one I posted to the VS2005 bug report database:

{
int num;
bool fValid;
try
{
num = Convert.ToInt32("50");
fValid = true;
}
catch (InvalidCastException)
{
fValid = false;
}
if (fValid)
{
Console.WriteLine("Value of number is " + num); // CS0165 here
}
}

My bug report was rejected as "by design", with the argument that it would
be too complicated for the compiler to figure out that fValid is actually
initialized in all code paths leading to its use. Note that there's no
looping, nor any interdependency between variables. It's a strictly "code
goes through here, or it goes through here" sort of thing. The only way
for the code to not reach "fValid = true" is for an exception to occur, in
which case it will reach "fValid = false" before it reaches the "if()"
statement.

Pete
May 8 '07 #22
On May 8, 9:44 am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Mon, 07 May 2007 22:58:27 -0700, Jon Skeet [C# MVP] <s...@pobox.com>
wrote:
Could you give an example? Here's one that *does* work:

Sure. Here's the one I posted to the VS2005 bug report database:

{
int num;
bool fValid;
try
{
num = Convert.ToInt32("50");
fValid = true;
}
catch (InvalidCastException)
{
fValid = false;
}
if (fValid)
{
Console.WriteLine("Value of number is " + num); // CS0165 here
}

}

My bug report was rejected as "by design", with the argument that it would
be too complicated for the compiler to figure out that fValid is actually
initialized in all code paths leading to its use. Note that there's no
looping, nor any interdependency between variables.
Umm... apart from the the interdependency between fValid and num?

May 8 '07 #23
On Tue, 08 May 2007 11:06:13 -0700, Bruce Wood <br*******@canada.com>
wrote:
Umm... apart from the the interdependency between fValid and num?
It's not any different from the "interdependency" between "args.Length"
and "x" in Jon's example. Given that, I presume that Jon's use of the
term "interdependency" refers to something more complex and I answered in
the same vein.

Pete
May 8 '07 #24
valentin tihomirov <no**************@yandex.ruwrote:
The rule: "Only initialized variables are allowed to be used" seems natural
and ultimately simple. The rules describing where you cut the analisys
should be extremely complex, I beleive.
The more complex the rules are, the harder they are to reason about and
understand. They also make it much harder to verify that a compiler is
correct.

I like languages where the rules are reasonably easy to understand,
even if that means that occasionally I have to spell things out a bit
more for the compiler's benefit.

--
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
May 8 '07 #25
Peter Duniho <Np*********@nnowslpianmk.comwrote:
On Mon, 07 May 2007 22:58:27 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
Could you give an example? Here's one that *does* work:

Sure. Here's the one I posted to the VS2005 bug report database:

{
int num;
bool fValid;
try
{
num = Convert.ToInt32("50");
fValid = true;
}
catch (InvalidCastException)
{
fValid = false;
}
if (fValid)
{
Console.WriteLine("Value of number is " + num); // CS0165 here
}
}

My bug report was rejected as "by design", with the argument that it would
be too complicated for the compiler to figure out that fValid is actually
initialized in all code paths leading to its use. Note that there's no
looping, nor any interdependency between variables.
There certainly *is* an interdependency between variables. The only
reason it will always actually work is that there is no way for fValid
to be true unless num has already been assigned.

It's a factor of the behaviour of the value's assigned, not just flow
control - and the rules in the spec are almost entirely based on flow
control, IIRC.

A simple way to demonstrate that is to change the behaviour of the
catch block - change the false to true, and consider the case where
Convert.ToInt32 throws an InvalidCastException - it would try to read
the value of num without it being assigned.

For the assignment status of one variable in a block to depend on the
value used in an assignment statement involving a *different* variable
seems way too complicated to be able to specify in a sensible way, IMO.

I certainly wouldn't deem your example "simple" (in terms of the
reasoning the compiler would have to go through to verify that it will
always have been assigned) - nor does it agree with your description of
"code that has just two branches, both of which initialize the
variable". Both the branches (success and catching
InvalidCastException) initialize fValid, but that's not the variable
the compiler is complaining about.

--
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
May 8 '07 #26
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Umm... apart from the the interdependency between fValid and num?

It's not any different from the "interdependency" between "args.Length"
and "x" in Jon's example. Given that, I presume that Jon's use of the
term "interdependency" refers to something more complex and I answered in
the same vein.
My example was one which matched your description of "code that has
just two branches, both of which initialize the variable". The x
variable is initialized regardless of the value of args.Length -
whereas in your example, num can only be regarded as being definitely
assigned if fValid is true.

--
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
May 8 '07 #27
On Tue, 08 May 2007 11:28:59 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
There certainly *is* an interdependency between variables. The only
reason it will always actually work is that there is no way for fValid
to be true unless num has already been assigned.
Ah. I see. I misinterpreted "interdependency" somehow. Hindsight being
20/20, I don't see how I did that. But I did. My mistake.

Still, I don't find this example overly complicated. After exiting the
try/catch block, there are a limited number of values that "fValid" can
have, one of which is tied to the initialization of "num" as well as the
use of "num". That is, at the point of evaluating the use of "num", the
compiler could easily detect that the block of code it's looking at only
occurs when "num" is initialized.

That said, I'm not really interested in debating whether the compiler
ought to or ought not to handle this. It doesn't today, it appears that
there is no chance it will ever handle it, and thus I find it pointless to
debate whether it ought to or not. The debate is moot and a waste of
time. Suffice to say I feel one way, others feel a different way.

Most particularly though, it's clear to me that in many cases, the current
behavior hides the very type of bug it's supposed to prevent. I find this
distasteful, if not unacceptable. In the interest of simplifying the
language (specification or compiler), the usefulness of the error has been
significantly reduced.

Pete
May 8 '07 #28
Peter Duniho <Np*********@nnowslpianmk.comwrote:
There certainly *is* an interdependency between variables. The only
reason it will always actually work is that there is no way for fValid
to be true unless num has already been assigned.

Ah. I see. I misinterpreted "interdependency" somehow. Hindsight being
20/20, I don't see how I did that. But I did. My mistake.

Still, I don't find this example overly complicated. After exiting the
try/catch block, there are a limited number of values that "fValid" can
have, one of which is tied to the initialization of "num" as well as the
use of "num". That is, at the point of evaluating the use of "num", the
compiler could easily detect that the block of code it's looking at only
occurs when "num" is initialized.
I think your idea of "easily" is different to mine :) I'd be interested
to see how you'd express the difference between the case where fValid
is true and the case where it's false in a way that doesn't make for a
horrendously complicated spec.
That said, I'm not really interested in debating whether the compiler
ought to or ought not to handle this. It doesn't today, it appears that
there is no chance it will ever handle it, and thus I find it pointless to
debate whether it ought to or not. The debate is moot and a waste of
time. Suffice to say I feel one way, others feel a different way.
Fair enough.
Most particularly though, it's clear to me that in many cases, the current
behavior hides the very type of bug it's supposed to prevent. I find this
distasteful, if not unacceptable. In the interest of simplifying the
language (specification or compiler), the usefulness of the error has been
significantly reduced.
It's been reduced *occasionally*. For the vast majority of code, it
does the right thing, without making the spec particularly complicated.
As someone who likes to be able to reason about the correct behaviour
of the compiler without taking hours about it (and the spec already
falls down on this criterion in some places) I'm happy with the balance
that's been struck.

--
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
May 8 '07 #29
On Tue, 08 May 2007 12:02:52 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
I think your idea of "easily" is different to mine :) I'd be interested
to see how you'd express the difference between the case where fValid
is true and the case where it's false in a way that doesn't make for a
horrendously complicated spec.
Well, that comes down to the question of language design and
specification. *Far* outside my area of expertise, and I admit I don't
have any good answers for how one would express this in a reasonable,
concise specification.

But the implementation details don't seem onerous to me. I guess the main
problem would be that even solving the simpler cases I'm complaining
about, one would still be left with situations where the variable is
initialized but not recognized as such (mainly where the controlling
variable is set externally somehow or isn't a simple integral type, that
sort of thing).

I guess one thing that would reduce my complaint somewhat would be if the
error message were changed to reflect the fact that the compiler may be
mistaken. Instead of saying there's a use of an unassigned variable, it
might say something like "cannot determine that the variable is
assigned". Basically, instead of stating that the programmer has made a
mistake, admit that the code might be correct but that the compiler isn't
capable of determining that.

I know that might sound silly, but sometimes it all has to do with how
something is said. :)

Pete
May 8 '07 #30
The more complex the rules are, the harder they are to reason about and
understand. They also make it much harder to verify that a compiler is
correct.
And you respond to my post where I highlight that the only rule which is
need is "(1) never use unassigned vars". It is ultimately simple and easy to
understand.

I like languages where the rules are reasonably easy to understand,
even if that means that occasionally I have to spell things out a bit
more for the compiler's benefit.
Again, "Spelling out more" means here: shutting up the compiler checks by
garbage-initializing the vars. This is after you have artificially
overcomplicated your grammar by describing where our trivial rule [1] stops
working. You are happy doing nonsense for less security claming the
opposite.
I agree that the rare weird garbage initialization is better trade-off than
no cheking at all.
May 8 '07 #31
Peter Duniho <Np*********@nnowslpianmk.comwrote:

<snip>
I guess one thing that would reduce my complaint somewhat would be if the
error message were changed to reflect the fact that the compiler may be
mistaken. Instead of saying there's a use of an unassigned variable, it
might say something like "cannot determine that the variable is
assigned". Basically, instead of stating that the programmer has made a
mistake, admit that the code might be correct but that the compiler isn't
capable of determining that.

I know that might sound silly, but sometimes it all has to do with how
something is said. :)
I take your point - I would actually use the terminology from the spec,
and say that the variable is "not definitely assigned". For one thing,
that means that a google search would come up with appropriate bits of
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
May 8 '07 #32
valentin tihomirov <V_*********@best.eewrote:
The more complex the rules are, the harder they are to reason about and
understand. They also make it much harder to verify that a compiler is
correct.

And you respond to my post where I highlight that the only rule which is
need is "(1) never use unassigned vars". It is ultimately simple and easy to
understand.
It's not easy for the compiler to implement, nor for the specification
to make clear what should be allowed at compile time.

Note that there's a difference between "unassigned" and "not definitely
assigned according to the language specification". The compiler
prevents you from using the latter, which in turn always prevents the
former too.
I like languages where the rules are reasonably easy to understand,
even if that means that occasionally I have to spell things out a bit
more for the compiler's benefit.

Again, "Spelling out more" means here: shutting up the compiler checks by
garbage-initializing the vars. This is after you have artificially
overcomplicated your grammar by describing where our trivial rule [1] stops
working. You are happy doing nonsense for less security claming the
opposite.
In some cases, yes. It's far from an "every day" occurrence
I agree that the rare weird garbage initialization is better trade-off than
no cheking at all.
But you would rather see a specification which is insanely complicated?

Exactly how far would you go, anyway? Consider the following program:

using System;

class Program
{
static void Main(string[] args)
{
int x;

if (ReturnTrue())
{
x = 5;
}
Console.WriteLine (x);
}

static bool ReturnTrue()
{
return true;
}
}

Should the compiler have to cope with that case as well, realising that
ReturnTrue() will always return true, and therefore x will always be
assigned a value?

How about:

using System;

class Program
{
static void Main(string[] args)
{
int x;

object o = SomeOtherClass.GetSomeReference();

if (IsNull(o) || !IsNull(o))
{
x = 5;
}
Console.WriteLine (x);
}

static bool IsNull(object o)
{
return o==null;
}
}

Now, *we* can work out that IsNull won't change its return value
between calls, and so it ends up as if (someBool || !someBool) which is
always going to be true, but would you expect the compiler to?

Sooner or later there will always be a boundary which the compiler
can't cross, unless you expect it to effectively solve the halting
problem - at which point I don't even want to *imagine* the spec.

In other words, there's a balance to be made between
compiler/specification complexity and never having to introduce an
assignment just for the sake of the compiler. I think the C# designers
got the balance about right - the spec is reasonably readable, and it
still relatively rarely complains at the wrong time.

Can you list exactly which extra situations you'd include, and which
you'd consider too complicated?

--
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
May 8 '07 #33
On Tue, 08 May 2007 13:07:55 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
[...]
Can you list exactly which extra situations you'd include, and which
you'd consider too complicated?
Well, I'm not valentin, but I would draw the line at local versus global.
That is, if it can be determined looking only at the current function,
then it should be. Conversely, it's fair to accept that the compiler
should not have to follow calls and analyze side-effects to do the
analysis.

As I mentioned elsewhere, I admit that this means there will still be
cases where the variable is assigned, but not detected as "definitely
assigned". But it would go a long way to addressing the "I can look at
just this code and know the variable is assigned" issue.

And of course, as mentioned before, rewording the error would be good
too. I agree with your suggestion to use "not definitely assigned" so
that a Google search can lead the programmer to a more relevant discussion.

Pete
May 8 '07 #34
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Can you list exactly which extra situations you'd include, and which
you'd consider too complicated?

Well, I'm not valentin, but I would draw the line at local versus global.
That is, if it can be determined looking only at the current function,
then it should be. Conversely, it's fair to accept that the compiler
should not have to follow calls and analyze side-effects to do the
analysis.
<snip>

How far should it have to go with the local analysis though? Here's an
example with simple booleans, which I suspect you'd want to pass:

static void Foo(bool a, bool b)
{
int c;
if (a && b)
{
c = 5;
}
if (b && !a)
{
c = 10;
}
if (!b)
{
c = 15;
}
Console.WriteLine (c);
}

Now let's make it a *bit* harder:

static void Foo(int a, bool b)
{
int c;
if ((a==10) && b)
{
c = 5;
}
if (b && (a != 10)
{
c = 10;
}
if (!b)
{
c = 15;
}
Console.WriteLine (c);
}

Here it the compiler would have to realise that the value of a couldn't
be equal to 10 and not equal to 10 at the same time.
Now let's make it really hard (but still only using locals):

static void Foo(int a, int b)
{
int c;

if (a < 0 || a 5 || b < 0 || b 5)
{
c = 0;
}
if (a+b < 10)
{
c = 1;
}
Console.WriteLine (c);
}

My *guess* is that you'd allow that to be too hard for the compiler to
understand (even though it meets your "can be determined looking only
at the current function" criterion) - but what about the middle
example? Easy enough or not?

--
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
May 8 '07 #35
On May 8, 12:44 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
My bug report was rejected as "by design", with the argument that it would
be too complicated for the compiler to figure out that fValid is actually
initialized in all code paths leading to its use. Note that there's no
looping, nor any interdependency between variables. It's a strictly "code
goes through here, or it goes through here" sort of thing. The only way
for the code to not reach "fValid = true" is for an exception to occur, in
which case it will reach "fValid = false" before it reaches the "if()"
statement.
While your code is simple and we can tell what you want, its also bad
design IMO. You're using exceptions to control program flow by simply
trying something to see if it bombs or not, and continuing on. If you
really don't want the ICE to stop your method from returning a value,
simply initting fValid to false before the try block and swallowing
the ICE is a better design.

Catch is meant to attempt to recover from an error; in this case,
there's nothing we can do to recover. The method may still be allowed
to execute (which is the case), so we simply do nothing.

May 8 '07 #36
Peter Duniho wrote:
Sure. Here's the one I posted to the VS2005 bug report database:

{
int num;
bool fValid;
try
{
num = Convert.ToInt32("50");
fValid = true;
}
catch (InvalidCastException)
{
fValid = false;
}
if (fValid)
{
Console.WriteLine("Value of number is " + num); // CS0165 here
}
}
To throw in my two cents, Convert.ToInt32( String ) is documented as
throwing two exceptions: FormatException and OverflowException. Neither
of which is InvalidCastException.
Unfortunately, this opens a path to the if that will leave it in an
uninitialized state.

--
Joel Lucsy
"The dinosaurs became extinct because they didn't have a space program."
-- Larry Niven
May 8 '07 #37
Joel Lucsy <jj*****@gmail.comwrote:

<snip>
To throw in my two cents, Convert.ToInt32( String ) is documented as
throwing two exceptions: FormatException and OverflowException. Neither
of which is InvalidCastException.
Unfortunately, this opens a path to the if that will leave it in an
uninitialized state.
No it doesn't - if either of those exceptions are thrown, the exception
will be bubbled up to the calling method without the "if" being
evaluated at at..

--
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
May 8 '07 #38
On Tue, 08 May 2007 13:56:13 -0700, Joel Lucsy <jj*****@gmail.comwrote:
To throw in my two cents, Convert.ToInt32( String ) is documented as
throwing two exceptions: FormatException and OverflowException. Neither
of which is InvalidCastException.
Unfortunately, this opens a path to the if that will leave it in an
uninitialized state.
Well, a) when I wrote that code, I am sure that either the documentation I
was consulting said to do what I did, or I simply empirically determined
that the InvalidCastException would be thrown in the case I cared about,
and b) you are wrong that there is a path for num being uninitialized but
used, since if a different exception is thrown it won't be caught by my
try/catch block and no more statements in that function will execute.

More generally, the code is just an example of the situation I'm talking
about. I guess it's par for the course on Usenet, but people ought to
think twice about whether there's really a point to critiquing the exact
nature of code that is posted simply for the purpose of demonstrating some
point unrelated to their critique.

IMHO, of course.

Pete
May 8 '07 #39
On Tue, 08 May 2007 13:34:59 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
How far should it have to go with the local analysis though? Here's an
example with simple booleans, which I suspect you'd want to pass:

static void Foo(bool a, bool b)
{
int c;
if (a && b)
{
c = 5;
}
if (b && !a)
{
c = 10;
}
if (!b)
{
c = 15;
}
Console.WriteLine (c);
}
No, actually I wouldn't expect that to pass. I agree that you don't need
to know the actual input values of a and b to resolve the question, but it
goes beyond what I expect the compiler to do. I really am just talking
about the very simplest cases, where the controlling variable is itself
initialized locally and the compiler can generate a list of known possible
values (or ranges of values) it will take on during the execution of the
method.

That sort of analysis is very basic, IMHO and would address most of the
obvious cases. As an example, the code you posted, while I can resolve
through logical analysis that c is definitely assigned, it is not readily
apparent just by inspecting the code, whereas I feel that it is in the
example I posted.

(Now...all that said, bools are a special case, in that there's only two
possible values for them anyway, and so the compiler could easily examine
all possibilities without doing the actual logical analysis. But I'm
satisfied saying that we don't need the compiler to treat bools as
different from other variable types, and so it doesn't need to take
advantage of the fact that they only have two possible values).

I suppose there's room for disagreement there too, but that's how I see it.

Pete
May 8 '07 #40
Peter Duniho <Np*********@nnowslpianmk.comwrote:

<snip my example>
No, actually I wouldn't expect that to pass. I agree that you don't need
to know the actual input values of a and b to resolve the question, but it
goes beyond what I expect the compiler to do.
<snip>

Out of interest (and not in any way trying to sound snide) do you know
of any languages/compilers which prevent access to possibly-unassigned
variables in this kind of way? I'm pretty sure Java's rules are similar
to C#'s. I don't recall it being part of the C/C++ spec at all,
although I'm much less familiar with those.

I do feel sorry for language designers when it comes to things like
this - they're never going to please everyone :(

--
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
May 8 '07 #41
On Tue, 08 May 2007 15:06:16 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
Out of interest (and not in any way trying to sound snide) do you know
of any languages/compilers which prevent access to possibly-unassigned
variables in this kind of way? I'm pretty sure Java's rules are similar
to C#'s. I don't recall it being part of the C/C++ spec at all,
although I'm much less familiar with those.
No...honestly I never really paid much attention to the issue until now.
And I don't think you sounded snide...it's a perfectly reasonable question.

I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any* checking
as opposed to more correct checking.
I do feel sorry for language designers when it comes to things like
this - they're never going to please everyone :(
Well, like I said, my concerns would probably be greatly addressed simply
by rewording the error. It's fair enough to say "this would make things
too complicated, so we don't do it", but I think it's also fair to say
that the compiler has no business making the absolute claim that a
variable's been used without being assigned unless it actually knows that
for sure.

Pete
May 8 '07 #42
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Out of interest (and not in any way trying to sound snide) do you know
of any languages/compilers which prevent access to possibly-unassigned
variables in this kind of way? I'm pretty sure Java's rules are similar
to C#'s. I don't recall it being part of the C/C++ spec at all,
although I'm much less familiar with those.

No...honestly I never really paid much attention to the issue until now.
And I don't think you sounded snide...it's a perfectly reasonable question.
Maybe I'm overly aware of how things can be interpreted in a completely
different way to the intended meaning :)
I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any* checking
as opposed to more correct checking.
I *seem* to remember that gcc had some checking like this, and
Microsoft's C compiler does with /Wall on, but it's not *hugely* smart
- it still complains at:

#include <stdio.h>

int main(void)
{
int x;
int y=1;
if (y==1)
{
x = 5;
}
printf ("%d", x);
}

Interestingly, the warning here talks about a "potentially
uninitialized local variable" - but if you remove the assignment in the
if statement, it turns the error into just "uninitialized local
variable".
I do feel sorry for language designers when it comes to things like
this - they're never going to please everyone :(

Well, like I said, my concerns would probably be greatly addressed simply
by rewording the error. It's fair enough to say "this would make things
too complicated, so we don't do it", but I think it's also fair to say
that the compiler has no business making the absolute claim that a
variable's been used without being assigned unless it actually knows that
for sure.
Agreed. I'd be happy to cast a vote for such an enhancement request :)

--
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
May 8 '07 #43
Jon Skeet [C# MVP] wrote:
Joel Lucsy <jj*****@gmail.comwrote:
>To throw in my two cents, Convert.ToInt32( String ) is documented as
throwing two exceptions: FormatException and OverflowException. Neither
of which is InvalidCastException.
Unfortunately, this opens a path to the if that will leave it in an
uninitialized state.

No it doesn't - if either of those exceptions are thrown, the exception
will be bubbled up to the calling method without the "if" being
evaluated at at..
Ah, right. My mistake. Must have been before my morning caffeine drip.

--
Joel Lucsy
"The dinosaurs became extinct because they didn't have a space program."
-- Larry Niven
May 9 '07 #44
On May 8, 5:06 pm, Jon Skeet [C# MVP] <s...@pobox.comwrote:
Peter Duniho <NpOeStPe...@nnowslpianmk.comwrote:
<snip>
I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any* checking
as opposed to more correct checking.

I *seem* to remember that gcc had some checking like this, and
Microsoft's C compiler does with /Wall on, but it's not *hugely* smart
- it still complains at:

#include <stdio.h>

int main(void)
{
int x;
int y=1;
if (y==1)
{
x = 5;
}
printf ("%d", x);

}

Interestingly, the warning here talks about a "potentially
uninitialized local variable" - but if you remove the assignment in the
if statement, it turns the error into just "uninitialized local
variable".
<snip>
gcc, aCC (HP-UX), and Digital Mars all complain in some fashion about
uninitialized variables if you set the warning level high enough. I'd
have to do some tests as to what the exact messages are. I've had
issues in the dark past with static locals being used without being
initialized and the compiler not catching that.

Tim

May 9 '07 #45
On May 8, 7:18 pm, Jon Skeet [C# MVP] <s...@pobox.comwrote:
The more complex the rules are, the harder they are to reason about and
understand. They also make it much harder to verify that a compiler is
correct.

I like languages where the rules are reasonably easy to understand,
even if that means that occasionally I have to spell things out a bit
more for the compiler's benefit.
I'm with Jon on this. I really can't recall more than a handful of
times over the last few years where I've needed to "unnecessarily"
initialise a variable just to please the compiler.

I'll happily do that if it means:

* The compiler is more efficient.
* The compiler codebase is smaller, making maintenance/enhancement
easier and reducing test cases.
* The compiler is less prone to bugs since the codebase/feature set is
smaller.
* The language specifications are smaller and less ambiguous, making
it easier for both users of the language and those implementing/
maintaining a compiler for it to understand (this includes Microsoft
and the Mono project)

I do wonder if Microsoft would have been able to make such relatively
rapid progress as they have with technologies such as LINQ -- much of
which is compiler-driven -- if there were lots more corner-cases for
them to deal with in the compiler and language specifications.
Regards,

Matt

May 9 '07 #46
Peter Duniho wrote:
On Tue, 08 May 2007 15:06:16 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
>Out of interest (and not in any way trying to sound snide) do you know
of any languages/compilers which prevent access to possibly-unassigned
variables in this kind of way? I'm pretty sure Java's rules are similar
to C#'s. I don't recall it being part of the C/C++ spec at all,
although I'm much less familiar with those.

No...honestly I never really paid much attention to the issue until
now. And I don't think you sounded snide...it's a perfectly reasonable
question.

I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any*
checking as opposed to more correct checking.
VC++ also has some basic checking. But in the case of the sample of
valentin t. the C++ compiler simply doesn't warn anymore.
That doesn't mean that the C++ is much better in detection, but simply
turns of the warning if it can't detect the usage of uninitialized
variables anymore.

[...]
Pete
May 10 '07 #47
valentin tihomirov wrote:
fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.
Nevertheless, compler forces me to do the useless initialization. Do the
designers of 'clever' robots forsee any overcoming for the limitations they
impose?
Why bother about the initialization at all ;-) ?
Performance ? Hardly. In your example jobId can be assigned multiple
times before fDeleted will be set to true.

Simply take the compiler error as a hint, that you can do some
optimizations of your own:

uint count = structures.count;
while (count-- 0) {
Struct struct = structures[count];
if (struct.type == JOB) {
if (struct.dataType == STATUS)
{
if ((struct.data & STATUS_DELETED) != 0 && first == false)
{
writeln(struct.id + " has completed");
break;
}
}
}

(hope it compiles ;-) )
This may not appropriate in your case and may be that in this case
reverse looping using an indexer may be slower (depends on the size of
the structures list).
Andre

May 10 '07 #48
>We're not talking about deeply nested, strangely-arranged loops, if()
>statements, etc. here. We're talking about code that has just two
branches, both of which initialize the variable, and yet the compiler
complains.

Could you give an example?
<skip>
Most examples which don't work (that I've seen) either involve for
loops or inter-dependency of two variables (if x is true then y is
definitely initialized).

class Undefined {

delegate void Del();
static void initialize(Del del) {
del();
}

public static void Main(string[] args) {

string user;
initialize(delegate() {
user = "x";
});

System.Console.WriteLine(user);
}
}
May 17 '07 #49
valentin tihomirov <V_*********@best.eewrote:
Most examples which don't work (that I've seen) either involve for
loops or inter-dependency of two variables (if x is true then y is
definitely initialized).


class Undefined {

delegate void Del();
static void initialize(Del del) {
del();
}

public static void Main(string[] args) {

string user;
initialize(delegate() {
user = "x";
});

System.Console.WriteLine(user);
}
}
I wouldn't class that as simple at all. Changing the implementation of
initialize (eg removing the body, or calling del.BeginInvoke() instead)
will change whether or not the variable is assigned a value.

Now, bear in mind the context of the discussion I was having with Peter
- he said there were "relatively simple" examples where the compiler
should be able to cope but doesn't.

I dread to think how complicated the spec would have to be in order to
be able to guarantee the behaviour here.

--
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
May 17 '07 #50

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

Similar topics

37
by: Grzegorz Staniak | last post by:
Hello, I'm a newbie Python user, a systems administrator - I've been trying to switch from Perl to Python for administrative tasks - and one thing I cannot understand so far is why I need the...
2
by: Jim Jewett | last post by:
Normally, I expect a subclass to act in a manner consistent with its Base classes. In particular, I don't expect to *lose* any functionality, unless that was the whole point of the subclass. ...
2
by: Marc | last post by:
Hi all, I was using Tkinter.IntVar() to store values from a large list of parts that I pulled from a list. This is the code to initialize the instances: def initVariables(self): self.e =...
15
by: aurora | last post by:
This may sound a little crazy. I capture the output of one class by redirecting the sys.stdout. However the is another threading running at the same time and occasionaly it output some messages to...
15
by: Ralf W. Grosse-Kunstleve | last post by:
****************************************************************************** This posting is also available in HTML format: http://cci.lbl.gov/~rwgk/python/adopt_init_args_2005_07_02.html...
18
by: Ralf W. Grosse-Kunstleve | last post by:
My initial proposal (http://cci.lbl.gov/~rwgk/python/adopt_init_args_2005_07_02.html) didn't exactly get a warm welcome... And Now for Something Completely Different: class autoinit(object):...
7
by: Andrew Robert | last post by:
Hi Everyone, I am having a problem with a class and hope you can help. When I try to use the class listed below, I get the statement that self is not defined. test=TriggerMessage(data) var...
24
by: Peter Maas | last post by:
The Python FAQ 1.4.5 gives 3 reasons for explicit self (condensed version): 1. Instance variables can be easily distinguished from local variables. 2. A method from a particular class can be...
84
by: braver | last post by:
Is there any trick to get rid of having to type the annoying, character-eating "self." prefix everywhere in a class? Sometimes I avoid OO just not to deal with its verbosity. In fact, I try to...
6
by: Bart Kastermans | last post by:
I am playing with some trees. In one of the procedures I wrote for this I am trying to change self to a different tree. A tree here has four members (val/type/left/right). I found that self = SS...
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
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.