digitalmars.D - switch break/fall (last minute request ... )
- Hasan Aljudy (29/29) Dec 25 2006 Maybe it's pointless asking this now, five days before v1.0, but I'll
- BCS (7/40) Dec 25 2006 banning fall through but retaining "goto case;" and "goto case value;"
- %u (11/16) Dec 25 2006 D
- Bill Baxter (23/41) Dec 25 2006 I'm pretty sure this one has been discussed to death in the past, so I
- Jason House (9/26) Dec 26 2006 I like this modified suggestion too.
- Hasan Aljudy (21/68) Dec 26 2006 This is so against the philosophy of D.
- Bill Baxter (17/96) Dec 26 2006 I didn't really get his argument either, so it's possible my
- mike (38/40) Dec 26 2006 I've once suggested this syntax:
- Craig Black (36/38) Dec 27 2006 I like this syntax. It fits better with the rest of the language. Howe...
Maybe it's pointless asking this now, five days before v1.0, but I'll give it a try. I would love it if there was a way to let the compiler catch the common bug of forgetting a "break" statement after a case clause in a switch statement. The C behavior of automatically falling through is a cause of many many bugs. It's really easy to forget a break and it's not really easy to discover this bug. I propose a new keyword, "fall", that would explicitly indicate the coder's intention of allowing the switch statement to fall through to the next case clause. The absence of either "fall" or "break" would indicate an error. Hypothetical example: ------------------ switch( X ) { case A: //something fall; <-- falls through to the next case case B: //something break; <-- break, same behavior as now case C: //something case D: <-- error, no break or fall statement before case D //something break; } -----------------
Dec 25 2006
Hasan Aljudy wrote:Maybe it's pointless asking this now, five days before v1.0, but I'll give it a try. I would love it if there was a way to let the compiler catch the common bug of forgetting a "break" statement after a case clause in a switch statement. The C behavior of automatically falling through is a cause of many many bugs. It's really easy to forget a break and it's not really easy to discover this bug. I propose a new keyword, "fall", that would explicitly indicate the coder's intention of allowing the switch statement to fall through to the next case clause. The absence of either "fall" or "break" would indicate an error. Hypothetical example: ------------------ switch( X ) { case A: //something fall; <-- falls through to the next case case B: //something break; <-- break, same behavior as now case C: //something case D: <-- error, no break or fall statement before case D //something break; } -----------------banning fall through but retaining "goto case;" and "goto case value;" would have the same effect. But for some reason I like your suggestion better. However, I'd rather just leave it all as it is. What we need is a D-lint tool that would could enforce a set of "Optional requirements". (Oh, cool name "D OptiOnal Requirements System", DOORS!!!!).
Dec 25 2006
== Quote from Hasan Aljudy (hasan.aljudy gmail.com)'s articlecase C: //something case D: <-- error, no break or fall statement before caseD So:case C:if( b1 ) { fall; break;} else if( b2) goto case C; else { break; fall;}case D:would be legal?
Dec 25 2006
%u wrote:== Quote from Hasan Aljudy (hasan.aljudy gmail.com)'s articleI'm pretty sure this one has been discussed to death in the past, so I doubt any last minute plea is going to change anything, for 1.0 at least. :-) Walter's position previously has been that he didn't want to confuse the poor C/C++/Java converts regardless of how error-prone default fall through is. If you look at the kind of code Walter writes (see parse.c in the DMD source in particular), you'll see that he is quite fond of stacking up multiple case labels, so I doubt he'd ever agree to make case TOKstruct: case TOKunion: case TOKclass: case TOKinterface: s = parseAggregate(); break; an error. However, what if you modify the rule slightly so that if a case follows another case immediately, then a 'fall' is not required? Then Walter may yet find it palatable. I'm all for it, though. I've been debugging my own missing 'break' statements for 20 years now, and I still never seem to learn. --bbcase C: //something case D: <-- error, no break or fall statement before caseD So:case C:if( b1 ) { fall; break;} else if( b2) goto case C; else { break; fall;}case D:would be legal?
Dec 25 2006
Bill Baxter wrote:If you look at the kind of code Walter writes (see parse.c in the DMD source in particular), you'll see that he is quite fond of stacking up multiple case labels, so I doubt he'd ever agree to make case TOKstruct: case TOKunion: case TOKclass: case TOKinterface: s = parseAggregate(); break; an error. However, what if you modify the rule slightly so that if a case follows another case immediately, then a 'fall' is not required? Then Walter may yet find it palatable. I'm all for it, though. I've been debugging my own missing 'break' statements for 20 years now, and I still never seem to learn.I like this modified suggestion too. Not to confuse the issue, but at least some thought should be given to using the continue keyword instead of a new keyword. The break keyword in switches already conflicts with the break keyword in loops... just like a continue keyword would too. I think the real show stopper is that it could lead to different behavior between C and D. I don't know if any thought has gone into disambiguating the continue (or break) keyword with nested loops. The same thing could be used here.
Dec 26 2006
Bill Baxter wrote:%u wrote:This is so against the philosophy of D. Nothing should be confusing, as the compiler would explicitly state in the error message that either "fall" or "break" must be present. Plus, Already many parts of D would confuse new comers, think about: foreach( item; items ) { ... } // Wait .. where was item defined? void func(X)(X y) { .. } // Wait .. why two sets of parameters? class X(Y) { .. } // Hmm .. is this D's way of defining inheritance? huh? like python?? class D : X { .. } // Hmm .. guess that X(Y) wasn't inheritance class A(B) : B, C, D // Now that's just plain confusing None of these examples is anymore confusing than requiring a "fall" or "break" for switch cases.== Quote from Hasan Aljudy (hasan.aljudy gmail.com)'s articleI'm pretty sure this one has been discussed to death in the past, so I doubt any last minute plea is going to change anything, for 1.0 at least. :-) Walter's position previously has been that he didn't want to confuse the poor C/C++/Java converts regardless of how error-prone default fall through is.case C: //something case D: <-- error, no break or fall statement before caseD So:case C:if( b1 ) { fall; break;} else if( b2) goto case C; else { break; fall;}case D:would be legal?If you look at the kind of code Walter writes (see parse.c in the DMD source in particular), you'll see that he is quite fond of stacking up multiple case labels, so I doubt he'd ever agree to make case TOKstruct: case TOKunion: case TOKclass: case TOKinterface: s = parseAggregate(); break; an error.Walter already solved this, in D you can do: case TOKstruct, TOKunion, TOKclass, TOKinterface: s = parseAggregate(); break;However, what if you modify the rule slightly so that if a case follows another case immediately, then a 'fall' is not required? Then Walter may yet find it palatable. I'm all for it, though. I've been debugging my own missing 'break' statements for 20 years now, and I still never seem to learn.Thanks for the testimony. I think this is true for *all* C/C++ programmers. I feel that fighting this common source of bug should've been one of the first things that D had done.--bb
Dec 26 2006
Hasan Aljudy wrote:Bill Baxter wrote:I didn't really get his argument either, so it's possible my paraphrasing of it somehow missed his real point. Or maybe it's just that he didn't like the idea of changing it to the point where 'break' was implicit and a fall-through keyword was required. But with your suggestion, as you say, the compiler will tell you if you're falling into C/C++ habits.%u wrote:This is so against the philosophy of D. Nothing should be confusing, as the compiler would explicitly state in the error message that either "fall" or "break" must be present.== Quote from Hasan Aljudy (hasan.aljudy gmail.com)'s articleI'm pretty sure this one has been discussed to death in the past, so I doubt any last minute plea is going to change anything, for 1.0 at least. :-) Walter's position previously has been that he didn't want to confuse the poor C/C++/Java converts regardless of how error-prone default fall through is.case C: //something case D: <-- error, no break or fall statement before caseD So:case C:if( b1 ) { fall; break;} else if( b2) goto case C; else { break; fall;}case D:would be legal?Plus, Already many parts of D would confuse new comers, think about: foreach( item; items ) { ... } // Wait .. where was item defined? void func(X)(X y) { .. } // Wait .. why two sets of parameters? class X(Y) { .. } // Hmm .. is this D's way of defining inheritance? huh? like python?? class D : X { .. } // Hmm .. guess that X(Y) wasn't inheritance class A(B) : B, C, D // Now that's just plain confusing None of these examples is anymore confusing than requiring a "fall" or "break" for switch cases.I didn't realize that worked. =) Actually I was thinking to suggest that, but figured that was a bigger lump of coal to swallow than just allowing adjacent cases to fall through. :-)If you look at the kind of code Walter writes (see parse.c in the DMD source in particular), you'll see that he is quite fond of stacking up multiple case labels, so I doubt he'd ever agree to make case TOKstruct: case TOKunion: case TOKclass: case TOKinterface: s = parseAggregate(); break; an error.Walter already solved this, in D you can do: case TOKstruct, TOKunion, TOKclass, TOKinterface: s = parseAggregate(); break;I agree. I think it was one of the first things that came to my mind when first looking into D, when I read the mantra on the D intro page about fixing design flaws in C/C++. "Oh great, that must mean the switch/break debacle is fixed ... hmm and what else I wonder". Come to find out that my first guess was wrong. --bb (P.S. This still ain't gonna happen in the next 3 days. ;-))However, what if you modify the rule slightly so that if a case follows another case immediately, then a 'fall' is not required? Then Walter may yet find it palatable. I'm all for it, though. I've been debugging my own missing 'break' statements for 20 years now, and I still never seem to learn.Thanks for the testimony. I think this is true for *all* C/C++ programmers. I feel that fighting this common source of bug should've been one of the first things that D had done.
Dec 26 2006
Am 26.12.2006, 23:26 Uhr, schrieb Hasan Aljudy <hasan.aljudy gmail.com>:=I feel that fighting this common source of bug should've been one of t=he =first things that D had done.I've once suggested this syntax: ' switch (foo) ' { ' case (0) writefln("one statement for case 0"); <-- doesn't fall = through ' case (1) ' { ' writefln("case 1"); ' writefln("has two statements"); ' } ' case (2, 3) ' { ' writefln("case 2 or case 3"); ' writefln("falls through to case 4); ' continue 4; ' } ' case (4) ' { ' writefln("case 4"); ' if (foo =3D=3D 2) break; // <-- break still breaks out of the = switch ' writefln("not case 2"); ' } ' else writefln("switch default"); ' } Still would like that better than the C syntax (and it saves a keyword!)= , = but, anyway: If you write the break as soon as you write the case label = = and then insert the code you'll never forget the break. This works, this= = way I never forgot a break in years. -mike -- = Erstellt mit Operas revolution=E4rem E-Mail-Modul: http://www.opera.com/= mail/
Dec 26 2006
I like this syntax. It fits better with the rest of the language. However, it's too different, so I don't think Walter would go for it. -Craig "mike" <vertex gmx.at> wrote in message news:op.tk6yflzgnxkcto zimmermoos... Am 26.12.2006, 23:26 Uhr, schrieb Hasan Aljudy <hasan.aljudy gmail.com>:I feel that fighting this common source of bug should've been one of the first things that D had done.I've once suggested this syntax: ' switch (foo) ' { ' case (0) writefln("one statement for case 0"); <-- doesn't fall through ' case (1) ' { ' writefln("case 1"); ' writefln("has two statements"); ' } ' case (2, 3) ' { ' writefln("case 2 or case 3"); ' writefln("falls through to case 4); ' continue 4; ' } ' case (4) ' { ' writefln("case 4"); ' if (foo == 2) break; // <-- break still breaks out of the switch ' writefln("not case 2"); ' } ' else writefln("switch default"); ' } Still would like that better than the C syntax (and it saves a keyword!), but, anyway: If you write the break as soon as you write the case label and then insert the code you'll never forget the break. This works, this way I never forgot a break in years. -mike -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/
Dec 27 2006