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

Please confirm this is a MSFT bug

Hi there,

Before I notify MSFT, can someone confirm this is in fact a compiler bug (it
seems pretty obvious but I'm fairly new to C#). The following code
(erroneously) generates compiler error CS0177 (The out parameter 'Whatever'
must be assigned to before control leaves the current method).

public void SomeFunc(out string Whatever)
{
bool Continue = ShouldWeContinue();
if (Continue)
{
Whatever = "Continue";
}

if (!Continue)
{
Whatever = "Didn't continue";
}
}

Jun 30 '06 #1
30 2746
Jake,

The compiler error is correct - you must assign a value to 'Whatever'
before leaving the method. Your code could easily be updated to do this
as so:

bool Continue = ShouldWeContinue();
if (Continue)
Whatever = "Continue";
else
Whatever = "Didn't continue";

Hope this helps.
Dan Manges

Jake Forson wrote:
Hi there,

Before I notify MSFT, can someone confirm this is in fact a compiler bug (it
seems pretty obvious but I'm fairly new to C#). The following code
(erroneously) generates compiler error CS0177 (The out parameter 'Whatever'
must be assigned to before control leaves the current method).

public void SomeFunc(out string Whatever)
{
bool Continue = ShouldWeContinue();
if (Continue)
{
Whatever = "Continue";
}

if (!Continue)
{
Whatever = "Didn't continue";
}
}

Jun 30 '06 #2
> Jake,

The compiler error is correct - you must assign a value to 'Whatever'
before leaving the method. Your code could easily be updated to do this
as so:

bool Continue = ShouldWeContinue();
if (Continue)
Whatever = "Continue";
else
Whatever = "Didn't continue";

Hope this helps.


Thanks for the feedback. It does assign it in all cases however which is why
I consider it a bug.
Jun 30 '06 #3
As written, yes - we can observe that it will always have a value by the
time it exits.

However: if the variable was a field, or if the variable was used in a (2.0)
anonymous delegate (as a /captured/ variable), then it would be possible for
(without it being obvious in the code) another thread to alter the value of
Continue between the two calls, which incidentally may or may-not be spotted
depending on volatility / memory-barriers. Given this, it makes a lot of
sense for me for the compiler to follow the "keep it simple" principle, and
consider all three cases equally - otherwise you would have to remember daft
rules about when each applies, and making a change (like using it in an
anonymous delegate) would suddenly cause unrelated code to not compile.

Does that make sense?

Marc
Jun 30 '06 #4
"Jake Forson" <no_spam@_nospam.com> wrote in message
news:eS**************@TK2MSFTNGP02.phx.gbl...
Jake,

The compiler error is correct - you must assign a value to 'Whatever'
before leaving the method. Your code could easily be updated to do this
as so:

bool Continue = ShouldWeContinue();
if (Continue)
Whatever = "Continue";
else
Whatever = "Didn't continue";

Hope this helps.


Thanks for the feedback. It does assign it in all cases however which is
why I consider it a bug.


Not so much a bug as the compiler not being as smart as it could. From the
compilers point of view there are 2 seperate IF statements. There is only so
far the compiler can go when determining code paths.
It probably doesn't consider the actual contents of the if statements, so
worries about the consequences if neither one is true.

:-)

ChrisM.
Jun 30 '06 #5

"Jake Forson" <no_spam@_nospam.com> wrote in message
news:eS**************@TK2MSFTNGP02.phx.gbl...
Jake,

The compiler error is correct - you must assign a value to 'Whatever'
before leaving the method. Your code could easily be updated to do this
as so:

bool Continue = ShouldWeContinue();
if (Continue)
Whatever = "Continue";
else
Whatever = "Didn't continue";

Hope this helps.


Thanks for the feedback. It does assign it in all cases however which is
why I consider it a bug.

Yes, it does assign it in all cases, but are they supposed to check every if
statement to see if it is an exact opposite of every other if statement.
Seems pretty silly and I don't see it as a bug.

This code:
private bool TestThis()
{
bool Continue = ShouldWeContinue();
if (Continue)
{
return true;
}

if (!Continue)
{
return false;
}
}

Produces "Not all code paths return a value" which I don't see as a bug
either. Yes, these simple examples are easy to check. But, it could
actually get way too complex to check.
Jun 30 '06 #6
> As written, yes - we can observe that it will always have a value by the
time it exits.

However: if the variable was a field, or if the variable was used in a
(2.0) anonymous delegate (as a /captured/ variable), then it would be
possible for (without it being obvious in the code) another thread to
alter the value of Continue between the two calls, which incidentally may
or may-not be spotted depending on volatility / memory-barriers. Given
this, it makes a lot of sense for me for the compiler to follow the "keep
it simple" principle, and consider all three cases equally - otherwise you
would have to remember daft rules about when each applies, and making a
change (like using it in an anonymous delegate) would suddenly cause
unrelated code to not compile.

Does that make sense?


Thanks for the info. While the KISS principle may apply here (on that we
agree), I'm at odds with your other points. It's certainly easier to parse
code without worrying about trapping this type of scenario and even
beneficial if it imrpoves compiler performance and robustness, but it's
still legal IMO (or should be). I doubt the C# standard says otherwise (I'd
be surprised to find out). As for your threading point, I don't follow this
at all :) I'm not familiar with threading in .NET yet, but in the usual
case, it's normally up to the programmer to properly synchronize access to
shared resources accordingly. I don't see how threading plays into this
scenario at all (assuming the programmer is doing his job but again, I'm not
familiar with the .NET threading model). In any case, while this is hardly a
blocking issue, it does force the programmer to re-work what appears to be
perfectly legal code (and this contrived example is just a dumbed down
version of what I really wanted to do but can't). Anyway, thanks again for
the feedback.
Jun 30 '06 #7
> Not so much a bug as the compiler not being as smart as it could. From the
compilers point of view there are 2 seperate IF statements. There is only
so far the compiler can go when determining code paths.
It probably doesn't consider the actual contents of the if statements, so
worries about the consequences if neither one is true.


Unless the standard says otherwise (or defines it as an implementation
detail which prevents you from writing portable code so it seems very
unlikely), it is therefore a bug IMO. The compiler is supposed to parse the
code according to the rules so as long as I've assigned something to my
"out" parameter, I've met my own burden so the compiler should meet its :)
Jun 30 '06 #8
Hi,

Personally I find the compiler answer correct.

It would not happen if you do

if (Continue)
{
Whatever = "Continue";
}
else
Whatever = "Didn't continue";
And in any case it's not a bug, it would be more like an optimization

--
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"Jake Forson" <no_spam@_nospam.com> wrote in message
news:%2******************@TK2MSFTNGP02.phx.gbl...
Hi there,

Before I notify MSFT, can someone confirm this is in fact a compiler bug
(it seems pretty obvious but I'm fairly new to C#). The following code
(erroneously) generates compiler error CS0177 (The out parameter
'Whatever' must be assigned to before control leaves the current method).

public void SomeFunc(out string Whatever)
{
bool Continue = ShouldWeContinue();
if (Continue)
{
Whatever = "Continue";
}

if (!Continue)
{
Whatever = "Didn't continue";
}
}

Jun 30 '06 #9
Hi,

Thanks for the feedback. It does assign it in all cases however which is
why I consider it a bug.


Well, you selected the most obvious option, bool which only have two
possible values. what if instead you select an enum (or in an even more
extreme case an int) ?
Would you expect the compiler to keep track if you used all the possible
values?

Too much work IMO.

--
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Jun 30 '06 #10
> Hi,

Personally I find the compiler answer correct.

It would not happen if you do

if (Continue)
{
Whatever = "Continue";
}
else
Whatever = "Didn't continue";
And in any case it's not a bug, it would be more like an optimization


I don't see how it qualifies as an optimization :) A language is defined by
a standard which sets down all rules that you must follow. Unless the
standard stipulates certain rules or conventions that render this example
illegal (I don't have a copy in front of me to check), then I'm not
violationg any rules so the compiler is in error :)
Jun 30 '06 #11
>> Thanks for the feedback. It does assign it in all cases however which is
why I consider it a bug.


Well, you selected the most obvious option, bool which only have two
possible values. what if instead you select an enum (or in an even more
extreme case an int) ?
Would you expect the compiler to keep track if you used all the possible
values?

Too much work IMO.


Again, the compiler doesn't define the language. The standard does and the
compiler must follow it even if it doesn't like it. Otherwise it's not a
compliant compiler and this should be stipulated somewhere. In this case
especially, since MSFT created C#, they're not following their own rules
(assuming this example is in fact legal - I wouldn't mind hearing from a
language lawyer on the subject)
Jun 30 '06 #12

"Jake Forson" <no_spam@_nospam.com> wrote in message
news:ex*************@TK2MSFTNGP04.phx.gbl...
Not so much a bug as the compiler not being as smart as it could. From
the compilers point of view there are 2 seperate IF statements. There is
only so far the compiler can go when determining code paths.
It probably doesn't consider the actual contents of the if statements, so
worries about the consequences if neither one is true.


Unless the standard says otherwise (or defines it as an implementation
detail which prevents you from writing portable code so it seems very
unlikely), it is therefore a bug IMO. The compiler is supposed to parse
the code according to the rules so as long as I've assigned something to
my "out" parameter, I've met my own burden so the compiler should meet its
:)


Yeeeaaa...

OK, so granted it is clear (to you and me) that in your case, either one or
the other of the if statements will definatly be true, and the compiler
could (I suppose) be smart enough to work that out.
However, how complex to you expect the compiler to get?

How about:

int testValue;
testValue = GetMyTestValue();
if (testValue <=5)
Whatever = "Continue";
if (testValue >=6)
Whatever = "Dont Continue";

should that compile?

what then if we change the first line to

double testValue;

I think it is also true that your original way of writing the method is
probably not the 'correct' way to write it. If it is written in the
'correct' way, that is as an IF..THEN..ELSE then the compiler is perfectly
happy with it.

;-P

ChrisM.
Jun 30 '06 #13
> I don't see how threading plays into this scenario at all (assuming the
programmer is doing his job but again <snip> The compiler does not (nor should not) enforce thread-synchronisation around
fields; this means that from the compiler's point-of-view the scenario I
posted is entirely plausible, so (if a field of captured variable) it *must*
barf at this.
your threading point, I don't follow this at all <snip>


The following code demonstates the /captured/ variable issue:

bool Continue = ShouldWeContinue();
something.SomeEvent += delegate {
DoSomething(ref Continue);
};
if (Continue) // ... etc as before

Now, SomeEvent could fire between the two "if" tests, changing the value of
Continue, and hence our return-variable might never be assigned. So: even in
a very simple example it is impossible to define a single behaviour that
works consistently for variables, fields and captured variables, *let alone*
properties and methods. As Jeff observes, with only a few more lines of code
it could get *must* more complex, too much so for either the compiler or
developer to validate that each route leaves a valid state.

So: it would only ever work with the most noddy of examples : why complicate
the compiler for such a trivial case? Why not just be consistent and
*either* assign a default value at initialisation, *or* use if/else so that
each route can be easily traced.

Marc
Jun 30 '06 #14
> OK, so granted it is clear (to you and me) that in your case, either one
or the other of the if statements will definatly be true, and the compiler
could (I suppose) be smart enough to work that out.
However, how complex to you expect the compiler to get?

How about:

int testValue;
testValue = GetMyTestValue();
if (testValue <=5)
Whatever = "Continue";
if (testValue >=6)
Whatever = "Dont Continue";

should that compile?
Of course it should if the standard says so. The standard wags the
(compiler's) tail, not the other way around.
I think it is also true that your original way of writing the method is
probably not the 'correct' way to write it. If it is written in the
'correct' way, that is as an IF..THEN..ELSE then the compiler is perfectly
happy with it.


There's nothing incorrect about it at all. It may be verbose, less efficient
(potentially) , etc., but it's not "incorrect" as far as the language is
concerned (again, subject to what the standard says). Note that this isn't a
real world example anyway but is effectively the same as what I was trying
to do (which was much cleaner).
Jun 30 '06 #15
Jake Forson wrote:
Thanks for the feedback. It does assign it in all cases however
which is why I consider it a bug.


Well, you selected the most obvious option, bool which only have two
possible values. what if instead you select an enum (or in an even
more extreme case an int) ?
Would you expect the compiler to keep track if you used all the
possible values?

Too much work IMO.


Again, the compiler doesn't define the language. The standard does
and the compiler must follow it even if it doesn't like it. Otherwise
it's not a compliant compiler and this should be stipulated
somewhere. In this case especially, since MSFT created C#, they're
not following their own rules (assuming this example is in fact legal
- I wouldn't mind hearing from a language lawyer on the subject)


See section 12.3.5 of ECMA-334.

http://www.ecma-international.org/pu...T/Ecma-334.pdf

In your case, the compiler wins - it's not required to do the level of
analysis to prove that the two if statements in your example are mutually
exclusive, so your two if statements don't constitute definite assignment to
the variable according to the rules.

-cd
Jun 30 '06 #16
>
your threading point, I don't follow this at all <snip>
The following code demonstates the /captured/ variable issue:

bool Continue = ShouldWeContinue();
something.SomeEvent += delegate {
DoSomething(ref Continue);
};
if (Continue) // ... etc as before

Now, SomeEvent could fire between the two "if" tests, changing the value
of Continue, and hence our return-variable might never be assigned. So:
even in a very simple example it is impossible to define a single
behaviour that works consistently for variables, fields and captured
variables, *let alone* properties and methods. As Jeff observes, with only
a few more lines of code it could get *must* more complex, too much so for
either the compiler or developer to validate that each route leaves a
valid state.


I'm not certain whether my point is defensible or even valid since I'm not
all that familiar with .NET threading. However, your example wouldn't
normally apply at all in this case (assuming I'm not out in left field as
far as .NET is conerned). If an event fires it will do so on another thread
and if that thread is going to modify "Continue" in anyway, then someone
(the programmer) needs to synchronize access to "Continue" using whatever
synchronization primitives the language (.NET) offers. IMHO this has nothing
to do with the original issue :)
Jun 30 '06 #17
Jake,

Two things:

a) If you think it is a bug, go and register it on the Product Feedback
center. If MS confirms it is a bug, they will put it in their system, if
not, they will tell you why. If you think it ^should^ be addressed, then
you can get votes for your suggestion, and assuming you get enough support,
it will help influence the product.

b) You keep talking about whether or not the compiler conforms to the spec.
The spec is at:

http://www.ecma-international.org/pu...T/Ecma-334.pdf

Furthermore, section 12.1.6 of the spec states:

Every output parameter of a function member shall be definitely assigned
(§12.3) before the function member returns normally.

If you then read section 12.3 (as well as re-read what some of the other
posters say), you will eventually see why your code is not legal. The
compiler can not guarantee that Continue will evaulate at ^runtime^ in such
a way that the code path will be hit, and therefore, can not guarantee that
the output variable will be set.

You are asking the compiler to do something which it is not defined (or
required) to do, which is to evaluate ^how^ the code paths will execute,
given all possible values.

There is no need to spam the group, btw, now that you have a) the spec
which you say the compiler should conform to, and b) a way to point out what
you consider to be a bug, and make a suggestion to change the compiler if it
is not (which it is not a bug).

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Jake Forson" <no_spam@_nospam.com> wrote in message
news:ek**************@TK2MSFTNGP02.phx.gbl...
Hi,

Personally I find the compiler answer correct.

It would not happen if you do

if (Continue)
{
Whatever = "Continue";
}
else
Whatever = "Didn't continue";
And in any case it's not a bug, it would be more like an optimization


I don't see how it qualifies as an optimization :) A language is defined
by a standard which sets down all rules that you must follow. Unless the
standard stipulates certain rules or conventions that render this example
illegal (I don't have a copy in front of me to check), then I'm not
violationg any rules so the compiler is in error :)

Jun 30 '06 #18
OK. I never said your example does this. What I am saying is that there
*are* separate, more complex, real-world examples (such as the one I
presented). My key point is that it is highly desirable that the language
and compiler can handle these situations according to a *single*
*consistent* set of rules.
If an event fires it will do so on another thread and if that thread is
going to modify "Continue" in anyway, then someone (the programmer) needs
to synchronize access to "Continue" using whatever


Again, from the compiler's perspective they don't *need* to; it is just a
damned good idea. The compiler enforces rules, not ideals. As such the
compiler *cannot* (ever) guard against threading foobars. It's hard enough
for the original developer to identify this!

But... at the end of the day, this whole discussion is a non-issue. It gets
raised on this list (and others) every week or so, and each time the weight
of opinion is with the compiler and the language spec. I will happily
conceed that spec conformance makes a far better reason "why", but IMO the
non-trivial examples like the above help provide counter-cases against what
you are proposing - *particularly* with a view to consistency between
use-cases. It *is* a realistic example; if I could be bothered I would knock
some code together to illustrate. But I can't be ;-p

Marc
Jun 30 '06 #19
> There is no need to spam the group, btw, now that you have a) the spec
which you say the compiler should conform to, and b) a way to point out
what you consider to be a bug, and make a suggestion to change the
compiler if it is not (which it is not a bug).


With all due respect, I'm not spamming this group. Nor do I wish to pursue
this issue ad nauseam. I'm trying to get to the bottom of it. I'm not a
programming novice (20+ years working in C/C++) and I know things aren't
always so cut-and-dry. People make their cases without knowing what the real
rules are and often quote from the standard without understanding it (not
necessarily in your case but in general - there's a lot of technical
legalese to wade through and it's easy to get things wrong). In any case,
now that I have the standard I can check for myself. Don't confuse someone
who's legimately defending a point however with someone who's being hostile
or argumentative (just because it seems that way to you).
Jun 30 '06 #20
> See section 12.3.5 of ECMA-334.

http://www.ecma-international.org/pu...T/Ecma-334.pdf

In your case, the compiler wins - it's not required to do the level of
analysis to prove that the two if statements in your example are mutually
exclusive, so your two if statements don't constitute definite assignment
to the variable according to the rules.


Thanks. I can now look into this myself. Case closed.
Jun 30 '06 #21
> OK. I never said your example does this. What I am saying is that there
*are* separate, more complex, real-world examples (such as the one I
presented). My key point is that it is highly desirable that the language
and compiler can handle these situations according to a *single*
*consistent* set of rules.
If an event fires it will do so on another thread and if that thread is
going to modify "Continue" in anyway, then someone (the programmer) needs
to synchronize access to "Continue" using whatever


Again, from the compiler's perspective they don't *need* to; it is just a
damned good idea. The compiler enforces rules, not ideals. As such the
compiler *cannot* (ever) guard against threading foobars. It's hard enough
for the original developer to identify this!

But... at the end of the day, this whole discussion is a non-issue. It
gets raised on this list (and others) every week or so, and each time the
weight of opinion is with the compiler and the language spec. I will
happily conceed that spec conformance makes a far better reason "why", but
IMO the non-trivial examples like the above help provide counter-cases
against what you are proposing - *particularly* with a view to consistency
between use-cases. It *is* a realistic example; if I could be bothered I
would knock some code together to illustrate. But I can't be ;-p


Ok, I think we still misunderstand eachother (to some extent) but I
appreciate your input. Thanks again.
Jun 30 '06 #22
"Jake Forson" <no_spam@_nospam.com> wrote:
Before I notify MSFT, can someone confirm this is in fact a compiler bug (it
seems pretty obvious but I'm fairly new to C#). The following code
(erroneously) generates compiler error CS0177 (The out parameter 'Whatever'
must be assigned to before control leaves the current method).

public void SomeFunc(out string Whatever)
{
bool Continue = ShouldWeContinue();
if (Continue)
{
Whatever = "Continue";
}

if (!Continue)
{
Whatever = "Didn't continue";
}
}


The problem is: where do you draw the line about what the compiler
infers from the code? We've got nice predictable rules now that are
solely based on the control-flow primitives and are not based on the
types of values in expressions. I think that's enough, and going down
the route you're suggesting (which is by design and not a bug, BTW)
would create more confusion than it's worth.

-- Barry

--
http://barrkel.blogspot.com/
Jun 30 '06 #23

Jake Forson wrote:
OK. I never said your example does this. What I am saying is that there
*are* separate, more complex, real-world examples (such as the one I
presented). My key point is that it is highly desirable that the language
and compiler can handle these situations according to a *single*
*consistent* set of rules.
If an event fires it will do so on another thread and if that thread is
going to modify "Continue" in anyway, then someone (the programmer) needs
to synchronize access to "Continue" using whatever


Again, from the compiler's perspective they don't *need* to; it is just a
damned good idea. The compiler enforces rules, not ideals. As such the
compiler *cannot* (ever) guard against threading foobars. It's hard enough
for the original developer to identify this!

But... at the end of the day, this whole discussion is a non-issue. It
gets raised on this list (and others) every week or so, and each time the
weight of opinion is with the compiler and the language spec. I will
happily conceed that spec conformance makes a far better reason "why", but
IMO the non-trivial examples like the above help provide counter-cases
against what you are proposing - *particularly* with a view to consistency
between use-cases. It *is* a realistic example; if I could be bothered I
would knock some code together to illustrate. But I can't be ;-p


Ok, I think we still misunderstand eachother (to some extent) but I
appreciate your input. Thanks again.


Marc's point can be summed up as follows:

If the variable you're testing is local to the method then yes, it
would be possible to determine that the two statements were mutually
exclusive if the compiler were to do that much analysis.

However, if the variable you're testing is a field, part of the
object's state, there is no guarantee that it does not change its value
between the two if statements, and therefore the compiler should
complain that it doesn't know for sure that you have assigned a value
to the "out" parameter.

Nonetheless, I suspect that the real answer is that it's not worth all
of the extra effort and extra code to have the compiler do the level of
analysis needed to determine whether various conditions cover all
possibilities.

Jun 30 '06 #24
Jake Forson <no_spam@_nospam.com> wrote:
Thanks for the info. While the KISS principle may apply here (on that we
agree), I'm at odds with your other points. It's certainly easier to parse
code without worrying about trapping this type of scenario and even
beneficial if it imrpoves compiler performance and robustness, but it's
still legal IMO (or should be). I doubt the C# standard says otherwise (I'd
be surprised to find out).


The C# standards are very clear on definite assignment, and they don't
contain any rules about the compiler performing any logic to determine
that one of two paths through code must be taken.

--
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
Jun 30 '06 #25

Jake Forson wrote:
With all due respect, I'm not spamming this group. Nor do I wish to pursue
this issue ad nauseam. I'm trying to get to the bottom of it. I'm not a
programming novice (20+ years working in C/C++) and I know things aren't
always so cut-and-dry. People make their cases without knowing what the real
rules are and often quote from the standard without understanding it (not
necessarily in your case but in general - there's a lot of technical
legalese to wade through and it's easy to get things wrong). In any case,
now that I have the standard I can check for myself. Don't confuse someone
who's legimately defending a point however with someone who's being hostile
or argumentative (just because it seems that way to you).


Jake, you said multiple times in this thread that it's the spec that
matters, not the language. Yet you never checked the spec, just
assumed that the compiler must be in error. That's why you're getting
this heat.

The standard's online (and on the first page of a Google "c# spec"
search. They'll even send you hard copies for free). It's not that
hard to read - why didn't you check it before (repeatedly) calling the
compiler non-compliant against that spec?

Jun 30 '06 #26
I disagree that this is the situation. Your real-world example is definitely
a very good example of why the compiler should catch this as it has done,
but I really don't believe that it's that smart.

I think it boils down to something like this ..

object DoSomething(ref out object obj) {
bool cond = true;
if (cond) { // compiler sees a condition
obj = true;
} // no else statement; set value to obj ignored

if (false) { // compiler sees a condition
obj = false;
} // no else statement; set value to obj ignored
}

object DoSomething(ref out object obj) {
bool cond = true;
if (cond) { // compiler sees a condition
obj = true; // check; double-check in else statement required
} else {
obj = false; // double-check; set value to obj recognized
}
}

Jon
"Marc Gravell" <ma**********@gmail.comwrote in message
news:OV**************@TK2MSFTNGP05.phx.gbl...
As written, yes - we can observe that it will always have a value by the
time it exits.

However: if the variable was a field, or if the variable was used in a
(2.0) anonymous delegate (as a /captured/ variable), then it would be
possible for (without it being obvious in the code) another thread to
alter the value of Continue between the two calls, which incidentally may
or may-not be spotted depending on volatility / memory-barriers. Given
this, it makes a lot of sense for me for the compiler to follow the "keep
it simple" principle, and consider all three cases equally - otherwise you
would have to remember daft rules about when each applies, and making a
change (like using it in an anonymous delegate) would suddenly cause
unrelated code to not compile.

Does that make sense?

Marc

Jul 2 '06 #27
Same principle applies to ..

enum enm {
a, b
}
bool DoSomethingElse(enm someEnum) {
switch (someEnum) { // someEnum can only be enm.a or enm.b
case enm.a:
return true;
case enm.b:
return false;
}
}

This will not compile. However, this will.

enum enm {
a, b
}
bool DoSomethingElse(enm someEnum) {
switch (someEnum) { // someEnum can only be enm.a or enm.b
case enm.a:
return true;
case enm.b:
default: <<<<< compiler will always set something
return false;
}
}
"Jon Davis" <jo*@REMOVE.ME.PLEASE.jondavis.netwrote in message
news:O7**************@TK2MSFTNGP04.phx.gbl...
>I disagree that this is the situation. Your real-world example is
definitely a very good example of why the compiler should catch this as it
has done, but I really don't believe that it's that smart.

I think it boils down to something like this ..

object DoSomething(ref out object obj) {
bool cond = true;
if (cond) { // compiler sees a condition
obj = true;
} // no else statement; set value to obj ignored

if (false) { // compiler sees a condition
obj = false;
} // no else statement; set value to obj ignored
}

object DoSomething(ref out object obj) {
bool cond = true;
if (cond) { // compiler sees a condition
obj = true; // check; double-check in else statement required
} else {
obj = false; // double-check; set value to obj recognized
}
}

Jon
"Marc Gravell" <ma**********@gmail.comwrote in message
news:OV**************@TK2MSFTNGP05.phx.gbl...
>As written, yes - we can observe that it will always have a value by the
time it exits.

However: if the variable was a field, or if the variable was used in a
(2.0) anonymous delegate (as a /captured/ variable), then it would be
possible for (without it being obvious in the code) another thread to
alter the value of Continue between the two calls, which incidentally may
or may-not be spotted depending on volatility / memory-barriers. Given
this, it makes a lot of sense for me for the compiler to follow the "keep
it simple" principle, and consider all three cases equally - otherwise
you would have to remember daft rules about when each applies, and making
a change (like using it in an anonymous delegate) would suddenly cause
unrelated code to not compile.

Does that make sense?

Marc


Jul 2 '06 #28
"Jon Davis" <jo*@REMOVE.ME.PLEASE.jondavis.netwrote:
Same principle applies to ..

enum enm {
a, b
}
The principle is actually quite different for enumerations. A bool
expression will always either evaluate to true or false, since (under
the CLI) it's based on integers being zero or non-zero.
bool DoSomethingElse(enm someEnum) {
switch (someEnum) { // someEnum can only be enm.a or enm.b
This statement is where it falls apart. The enumeration value "(enm) 3"
will fit into a variable of type enm without error, so it isn't true
that someEnum can only be enm.a or enm.b.

-- Barry

--
http://barrkel.blogspot.com/
Jul 2 '06 #29
"Barry Kelly" <ba***********@gmail.comwrote in message
news:2k********************************@4ax.com...
This statement is where it falls apart. The enumeration value "(enm) 3"
will fit into a variable of type enm without error, so it isn't true
that someEnum can only be enm.a or enm.b.
Fine, ignore the commented portion, I was just trying to paint a scenario. I
was demonstrating the switch requiring a default value, not the enum, a
point that is retained regardless of (enm)3.

Try pasting the sample into VS or SnippetCompiler and you'll see the same
error.

'MyClass.DoSomethingElse(MyClass.enm)': not all code paths return a value

Jon
Jul 2 '06 #30
Jon Davis <jo*@REMOVE.ME.PLEASE.jondavis.netwrote:
"Barry Kelly" <ba***********@gmail.comwrote in message
news:2k********************************@4ax.com...
This statement is where it falls apart. The enumeration value "(enm) 3"
will fit into a variable of type enm without error, so it isn't true
that someEnum can only be enm.a or enm.b.

Fine, ignore the commented portion, I was just trying to paint a scenario. I
was demonstrating the switch requiring a default value, not the enum, a
point that is retained regardless of (enm)3.

Try pasting the sample into VS or SnippetCompiler and you'll see the same
error.

'MyClass.DoSomethingElse(MyClass.enm)': not all code paths return a value
And it's absolutely right - if you pass in (enm)3 as the parameter,
then without the default case, your code would reach the end of the
method without returning anything. It's absolutely correct for the
compiler to complain about that.

It's not that switch requires a default, it's a matter of the
reachability of the end of the switch statement.

Now, the C# spec states:

<quote>
The end point of a switch statement is reachable if at least one of the
following is true:

* The switch statement contains a reachable break statement that
exits the switch statement.
* The switch statement is reachable, the switch expression is a
non-constant value, and no default label is present.
* The switch statement is reachable, the switch expression is a
constant value that doesn=3Ft match any case label, and no default label
is present.
</quote>

This is only actually conservative if the switch expression is a non-
constant value and you specify *every* value in the appropriate type as
a case label. For instance, if you were switching on a byte and all 256
possible values were specified and all of them returned, you'd still
have to have a default case. I can't remember ever seeing such a
situation, personally - so simplicity on the part of spec is
reasonable.

--
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
Jul 2 '06 #31

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

Similar topics

3
by: KathyB | last post by:
Hi, I've tried everything I can think of. Using the script below, I thought on submit my ConfirmSave function would run, then if true returned, would run my form action. At this point it appears...
7
by: Scotter | last post by:
Hi - Simple ASPX application not running. I've given the ASP.NET, IWAM, and USR accounts full permissions to the folder my application resides in. I don't know what else needs done on the server...
6
by: Tiraman | last post by:
Hi , I have a stored procedure which return an xml by using the (for xml auto/explicit) which working fine under the Query Analyzer . and i would like to build simple function that get the sp...
23
by: Jason | last post by:
Hi, I was wondering if any could point me to an example or give me ideas on how to dynamically create a form based on a database table? So, I would have a table designed to tell my application...
5
by: NewGuy | last post by:
I have this parameter: public string Title { get{return m_sTitle;} set{m_sTitle = value;} } I want to do this: Object foo = new Object;
3
by: Marc Jennings | last post by:
I have an architectural question that I would appreciate some input on, please. Earlier this year I spent some time in Sri Lanka working with a rpoject to help after the tsunami. A part of the...
10
by: Mike Malter | last post by:
I have scoured the web looking for an example of how to do a javascript confirm box in .NET. Is there any way to do it? Thanks.
7
by: Tigger | last post by:
Dear Experts, I am working on ASP.NET. I have got a problem related to the usage of Javascript in ASP.NET. Please help. The story is the following: 1) I am developing an ASP.NET application. I...
7
by: Jeff | last post by:
Hi - For my VB.NET app, I have a SQL2K database that I use to create a dataset with multiple data tables. I've created a dataview (dvReportsTo) of one of the tables, SCPMaster, and I've bound a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: 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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

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.