www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Switch case falltrhough, regression or intended behavior ?

reply "deadalnix" <deadalnix gmail.com> writes:
I have several instance of cases like this :

switch(c) {
	case 'U', 'u' :
	case 'L', 'l' :
		// code . . .
}

dmd from master complains about it (Error: switch case 
fallthrough - use 'goto case;' if intended). It used to work.

Note that in that case, the fix is trivial, but I don't really 
see the point in changing such behavior.
Feb 17 2013
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/17/13 11:10 AM, deadalnix wrote:
 I have several instance of cases like this :

 switch(c) {
 case 'U', 'u' :
 case 'L', 'l' :
 // code . . .
 }

 dmd from master complains about it (Error: switch case fallthrough - use
 'goto case;' if intended). It used to work.

 Note that in that case, the fix is trivial, but I don't really see the
 point in changing such behavior.

If there's no intervening code between cases, it should just work. Andrei
Feb 17 2013
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 17 Feb 2013 11:10:58 -0500, deadalnix <deadalnix gmail.com> wrote:

 I have several instance of cases like this :

 switch(c) {
 	case 'U', 'u' :
 	case 'L', 'l' :
 		// code . . .
 }

 dmd from master complains about it (Error: switch case fallthrough - use  
 'goto case;' if intended). It used to work.

 Note that in that case, the fix is trivial, but I don't really see the  
 point in changing such behavior.

looks like a bug. -Steve
Feb 17 2013
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Sunday, 17 February 2013 at 16:10:59 UTC, deadalnix wrote:
 dmd from master complains about it (Error: switch case 
 fallthrough - use 'goto case;' if intended). It used to work.

Does it happen on the staging branch as well? David
Feb 17 2013
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 17/02/2013 16:10, deadalnix wrote:
 I have several instance of cases like this :

 switch(c) {
      case 'U', 'u' :
      case 'L', 'l' :
          // code . . .
 }

 dmd from master complains about it (Error: switch case fallthrough - use 'goto
case;' if
 intended). It used to work.

Implicit fall through shouldn't have been allowed from the beginning. It would appear that this has finally been banned. However, according to the grammar, this is now illegal for a different reason: http://dlang.org/statement.html#SwitchStatement CaseStatement: case ArgumentList : ScopeStatementList ScopeStatementList: StatementListNoCaseNoDefault StatementListNoCaseNoDefault: StatementNoCaseNoDefault StatementNoCaseNoDefault StatementListNoCaseNoDefault But it does seem odd to people coming from C(++), since it doesn't seem aimed at either simplifying the grammar or shielding the programmer's foot against self-inflicted gunfire. But it does address this issue, which I actually hadn't taken in had been resolved http://d.puremagic.com/issues/show_bug.cgi?id=603 If we want to still allow the old C syntax for multiple cases, then we can define CaseStatement: case ArgumentList : ScopeStatementList case ArgumentList : CaseStatement which is only a small change.... Stewart.
Feb 17 2013
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 17/02/2013 20:07, Jonathan M Davis wrote:
<snip>
 Implicit fall through shouldn't have been allowed from the beginning.  It
 would appear that this has finally been banned.

Implicit fallthrough is a warning when a case stament is non-empty, but if it's empty (as in the example), then there is no warning.

What version of DMD are you using? I'm getting stranger than this (2.061): ----- switch_fallthrough_a.d ----- void main() { char c = 'x'; switch(c) { case 'U', 'u' : case 'L', 'l' : // code . . . default: } } ----- switch_fallthrough_b.d ----- void main() { char c = 'x'; switch(c) { case 'U', 'u' : c = 'q'; case 'L', 'l' : c = 'r'; // code . . . default: } } ---------- C:\Users\Stewart\Documents\Programming\D\Tests>dmd switch_fallthrough_a.d C:\Users\Stewart\Documents\Programming\D\Tests>dmd -w switch_fallthrough_a.d switch_fallthrough_a.d(5): Error: switch case fallthrough - use 'goto case;' if intended switch_fallthrough_a.d(7): Error: switch case fallthrough - use 'goto default;' if intended C:\Users\Stewart\Documents\Programming\D\Tests>dmd switch_fallthrough_b.d C:\Users\Stewart\Documents\Programming\D\Tests>dmd -w switch_fallthrough_b.d switch_fallthrough_b.d(6): Error: switch case fallthrough - use 'goto case;' if intended switch_fallthrough_b.d(9): Error: switch case fallthrough - use 'goto default;' if intended ---------- You see, it's independent of whether there are any statements between the two case markers, and there's a further anomaly in that it's an _error_ that's emitted only if _warnings_ are enabled.
 If the compiler is warning about falling through an empty case statement, it's
a bug.

There's no such thing as an "empty case statement", unless you mean the case where the ScopeStatementList is ";" or "{}" by itself. Look at the grammar carefully. So by the current spec, the first example is a syntax error, since a CaseStatement explicitly forbids another CaseStatement as its body. Stewart.
Feb 17 2013
next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 18/02/2013 01:10, Andrej Mitrovic wrote:
<snip>
 The grammar and spec are often broken. The OP sample is completely valid.

The whole point of a spec is to define the language. So if the spec makes some code illegal, then (at least for the time being) it is illegal. Stewart.
Feb 17 2013
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 18/02/2013 01:30, Jonathan M Davis wrote:
 On Monday, February 18, 2013 01:04:41 Stewart Gordon wrote:
 On 17/02/2013 20:07, Jonathan M Davis wrote:
 <snip>


 Implicit fallthrough is a warning when a case stament is non-empty, but if
 it's empty (as in the example), then there is no warning.

What version of DMD are you using?

That's irrelevant. I'm stating what the intended behavior is. If the compiler doesn't follow that behavior, then it's a bug.

So you meant to say "there is meant to be no warning". <snip>
 and there's a further anomaly in that it's an _error_
 that's emitted only if _warnings_ are enabled.

That's normal. That's what -w does. If you don't use any compiler flags, then you get no warnings. If you use -w, you get them, but they're treated as errors.

No, treatment as errors has nothing to do with the wording of compiler messages. It's completely independent of this. As I explained at 01:21 UTC.
 If you use -wi, then you get "informational warnings" which is what
 most everyone expects compilers to do normally - i.e. print the warning but
 not treat it as an error - but Walter Bright thinks differently about such
 things than many people, and his compilers often don't do what many people
 would consider normal. He doesn't believe in warnings in the first place.
 Rather, he thinks that everything should be an error or not as far as the
 compiler is concerned (which I very much agree with), but unfortunately, he
 gave in enough to create the -w flag (and eventually, the -wi flag), and when
he
 did, he didn't follow the behavior of your average compiler, which has
 generated a fair bit of confusion with regards to warnings.

Yes, Walter claimed early on that anything that compilers tend to emit warnings for ought to be forbidden by the language. However, he hasn't followed this principle, and so we were left with the awkward situation whereby certain kinds of obviously buggy (or at least suspect) code are just silently accepted. The "no warnings" philosophy we had for a while was also a detriment to one of D's other design goals, to have different compiler vendors competing on quality of implementation. Still, for as long as the language spec is still under development, one might as well make suspicious code illegal rather than putting warnings in the reference implementation (unless there really is a point of contention in what should be legal). But third party implementers don't have this recourse, so that's why warnings are useful. Part of what makes a quality implementation is what warnings it generates. Stewart.
Feb 17 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 17 February 2013 at 17:16:44 UTC, David Nadlinger 
wrote:
 On Sunday, 17 February 2013 at 16:10:59 UTC, deadalnix wrote:
 dmd from master complains about it (Error: switch case 
 fallthrough - use 'goto case;' if intended). It used to work.

Does it happen on the staging branch as well? David

I don't know and I can't test as I'm running a huge dustmite right now (likely to run all night long).
Feb 17 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 17, 2013 17:26:01 Stewart Gordon wrote:
 On 17/02/2013 16:10, deadalnix wrote:
 I have several instance of cases like this :
 
 switch(c) {
 
      case 'U', 'u' :
      
      case 'L', 'l' :
          // code . . .
 
 }
 
 dmd from master complains about it (Error: switch case fallthrough - use
 'goto case;' if intended). It used to work.

<snip> Implicit fall through shouldn't have been allowed from the beginning. It would appear that this has finally been banned.

Implicit fallthrough is a warning when a case stament is non-empty, but if it's empty (as in the example), then there is no warning. If the compiler is warning about falling through an empty case statement, it's a bug. - Jonathan M Davis
Feb 17 2013
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, deadalnix <deadalnix gmail.com> wrote:
 It used to work.

Are you sure it's a regression? 2.062: $ dmd test.d

$ dmd -w test.d
 test.d(8): Error: switch case fallthrough - use 'goto case;' if intended
 test.d(10): Error: switch case fallthrough - use 'goto default;' if intended

I've tested from 2.062 to 2.057 and they all have this behavior.
Feb 17 2013
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 17/02/2013 21:46, Jonathan M Davis wrote:
<snip>
 Hmm, that brings up a different (though minor) issue: If it's a
 warning, why does it say "Error"?

Probably because -w turns warnings into errors. That's its whole schtick.

No, the whole schtick of -w is that it causes warnings to be emitted at all. It's a quirk of the way it was designed that it treats them as errors - by returning a failure status code, not by the wording of the compiler output. But it's clearly a bug that this particular warning message has the label "Error:" instead of "Warning:". http://d.puremagic.com/issues/show_bug.cgi?id=952 Unless it really is meant to be an error, in which case it's a bug that it is emitted only if -w is used.
 However, -wi also appears to say "Error," which definitely isn't correct.

-wi versus -w shouldn't make any difference to the wording of error messages. Only to the status code returned by the compiler if there were any warnings. Stewart.
Feb 17 2013
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 18/02/2013 01:21, Stewart Gordon wrote:
 On 17/02/2013 21:46, Jonathan M Davis wrote:

 Probably because -w turns warnings into errors. That's its whole schtick.

No, the whole schtick of -w is that it causes warnings to be emitted at all. It's a quirk of the way it was designed that it treats them as errors - by returning a failure status code, not by the wording of the compiler output.

There's a more important way in which it isn't quite "treat warnings as errors": if you use an IsExpression to test the validity of a snippet of code, a pass with warnings must still be a pass. Otherwise, you'll get code that compiles with or without -w, but behaves differently in each case. There have been bugs in DMD in this respect - I'm not sure if there still are. Stewart.
Feb 24 2013
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 25/02/2013 02:01, Jonathan M Davis wrote:
<snip>
 There's a more important way in which it isn't quite "treat warnings as
 errors": if you use an IsExpression to test the validity of a snippet of
 code, a pass with warnings must still be a pass.  Otherwise, you'll get
 code that compiles with or without -w, but behaves differently in each
 case.  There have been bugs in DMD in this respect - I'm not sure if there
 still are.

That behavior is on purpose. It really is meant that the warnings be treated exactly as errors. I pointed out this particular issue to Walter in the past (within the past month even IIRC), and he agreed that it wasn't good, but it was clear from what he said that it was the intended behavior and not a bug.

So according to what you're saying, it's deliberate that -w doesn't compile D, but rather a vendor-specific language that is confusingly similar to D and admits some code that is legal in D with different behaviour. Please supply a link to Walter's statement.
 The problem is really that -w exists at all.

Together with the omission of a switch that simply causes warnings to be emitted and then returns an error status if any were. Stewart.
Feb 25 2013
prev sibling next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Sun, 17 Feb 2013 22:03:33 +0100
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 On 2/17/13, deadalnix <deadalnix gmail.com> wrote:
 It used to work.

Are you sure it's a regression? 2.062: $ dmd test.d

$ dmd -w test.d
 test.d(8): Error: switch case fallthrough - use 'goto case;' if
 intended test.d(10): Error: switch case fallthrough - use 'goto
 default;' if intended

I've tested from 2.062 to 2.057 and they all have this behavior.

Hmm, that brings up a different (though minor) issue: If it's a warning, why does it say "Error"?
Feb 17 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> wrote:
 Hmm, that brings up a different (though minor) issue: If it's a
 warning, why does it say "Error"?

I can see in the source there's a check for the -w flag but then an error is raised by mistake. This should either be an error regardless of -w or be changed into a warning.
Feb 17 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 On 2/17/13, Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> wrote:
 Hmm, that brings up a different (though minor) issue: If it's a
 warning, why does it say "Error"?

I can see in the source there's a check for the -w flag but then an error is raised by mistake. This should either be an error regardless of -w or be changed into a warning.

Well the OP sample might also be a rejects-valid. So there's 2 bugs here.
Feb 17 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, deadalnix <deadalnix gmail.com> wrote:
 I have several instance of cases like this :

 switch(c) {
 	case 'U', 'u' :
 	case 'L', 'l' :
 		// code . . .
 }

Found the report: http://d.puremagic.com/issues/show_bug.cgi?id=6552
Feb 17 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 17, 2013 16:08:13 Nick Sabalausky wrote:
 On Sun, 17 Feb 2013 22:03:33 +0100
 
 Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 On 2/17/13, deadalnix <deadalnix gmail.com> wrote:
 It used to work.

Are you sure it's a regression? 2.062: $ dmd test.d $ dmd -w test.d
 test.d(8): Error: switch case fallthrough - use 'goto case;' if
 intended test.d(10): Error: switch case fallthrough - use 'goto
 default;' if intended

I've tested from 2.062 to 2.057 and they all have this behavior.

Hmm, that brings up a different (though minor) issue: If it's a warning, why does it say "Error"?

Probably because -w turns warnings into errors. That's its whole schtick. However, -wi also appears to say "Error," which definitely isn't correct. - Jonathan M Davis
Feb 17 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 Probably because -w turns warnings into errors. That's its whole schtick.

Really? Man this is confusing..
 However, -wi also appears to say "Error," which definitely isn't correct.

Ok good to know. I'm making a pull for these fixes.
Feb 17 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/18/13, Stewart Gordon <smjg_1998 yahoo.com> wrote:
 There's no such thing as an "empty case statement", unless you mean the case
 where the
 ScopeStatementList is ";" or "{}" by itself.  Look at the grammar
 carefully.

 So by the current spec, the first example is a syntax error, since a
 CaseStatement
 explicitly forbids another CaseStatement as its body.

The grammar and spec are often broken. The OP sample is completely valid.
Feb 17 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, February 18, 2013 01:04:41 Stewart Gordon wrote:
 On 17/02/2013 20:07, Jonathan M Davis wrote:
 <snip>
 
 Implicit fall through shouldn't have been allowed from the beginning.  It
 would appear that this has finally been banned.

Implicit fallthrough is a warning when a case stament is non-empty, but if it's empty (as in the example), then there is no warning.

What version of DMD are you using?

That's irrelevant. I'm stating what the intended behavior is. If the compiler doesn't follow that behavior, then it's a bug.
 You see, it's independent of whether there are any statements between the
 two case markers,

Which is a bug.
 and there's a further anomaly in that it's an _error_
 that's emitted only if _warnings_ are enabled.

That's normal. That's what -w does. If you don't use any compiler flags, then you get no warnings. If you use -w, you get them, but they're treated as errors. If you use -wi, then you get "informational warnings" which is what most everyone expects compilers to do normally - i.e. print the warning but not treat it as an error - but Walter Bright thinks differently about such things than many people, and his compilers often don't do what many people would consider normal. He doesn't believe in warnings in the first place. Rather, he thinks that everything should be an error or not as far as the compiler is concerned (which I very much agree with), but unfortunately, he gave in enough to create the -w flag (and eventually, the -wi flag), and when he did, he didn't follow the behavior of your average compiler, which has generated a fair bit of confusion with regards to warnings.
 If the compiler is warning about falling through an empty case statement,
 it's a bug.

where the ScopeStatementList is ";" or "{}" by itself. Look at the grammar carefully. So by the current spec, the first example is a syntax error, since a CaseStatement explicitly forbids another CaseStatement as its body.

I mean a case statement with no statements in it. The only thing following it is another case statement or the closing brace of the switch statement. That sort of fallthrough is not supposed to generate a warning. If the grammar claims anything about empty case statements being illegal, then the spec is in error (which happens far too often). Walter has been very clear on the intended behavior. It's a warning to have implicit fallthrough except in the situation where the case statement is empty (because it would be very annoying to have to put a whole lot of gotos in case statements which are all supposed to shared the same code by falling through). If the compiler or grammar disagree with that, then it's a bug. Actually, looking at the most recent compiler, it's generating a deprecation message now, so it's been moved from warning to deprecated, and it _is_ generating the message for an empty case statement, which is wrong. - Jonathan M Davis
Feb 17 2013
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 17 Feb 2013 20:28:51 -0500, Stewart Gordon <smjg_1998 yahoo.com>  
wrote:

 On 18/02/2013 01:10, Andrej Mitrovic wrote:
 <snip>
 The grammar and spec are often broken. The OP sample is completely  
 valid.

The whole point of a spec is to define the language. So if the spec makes some code illegal, then (at least for the time being) it is illegal.

It's quite possible the spec has a bug. It's not perfect. -Steve
Feb 17 2013
prev sibling next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Sun, 17 Feb 2013 22:53:13 +0100
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 On 2/17/13, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 Probably because -w turns warnings into errors. That's its whole
 schtick.

Really? Man this is confusing..

The -w is just simply the "treat warnings as errors" switch (and of course it also implies "enable warnings"). Most compilers have an "enable warnings" switch and a "treat warnings as errors" switch. DMD is the same, it just treats "as errors" as the default instead of "as warnings" as the default. That is perhaps a little backwards, but it's partly because DMD didn't used to even *have* the "-wi" switch and the ability to treat warnings *not* as errors. Then we talked^H^H^H^H^H^Hharrassed Walter into adding -wi, and being such a good sport he obliged :)
Feb 18 2013
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, February 25, 2013 01:42:10 Stewart Gordon wrote:
 On 18/02/2013 01:21, Stewart Gordon wrote:
 On 17/02/2013 21:46, Jonathan M Davis wrote:

 Probably because -w turns warnings into errors. That's its whole schtick.

No, the whole schtick of -w is that it causes warnings to be emitted at all. It's a quirk of the way it was designed that it treats them as errors - by returning a failure status code, not by the wording of the compiler output.

<snip> There's a more important way in which it isn't quite "treat warnings as errors": if you use an IsExpression to test the validity of a snippet of code, a pass with warnings must still be a pass. Otherwise, you'll get code that compiles with or without -w, but behaves differently in each case. There have been bugs in DMD in this respect - I'm not sure if there still are.

That behavior is on purpose. It really is meant that the warnings be treated exactly as errors. I pointed out this particular issue to Walter in the past (within the past month even IIRC), and he agreed that it wasn't good, but it was clear from what he said that it was the intended behavior and not a bug. The problem is really that -w exists at all. - Jonathan M Davis
Feb 24 2013