digitalmars.D - About switch case statements...
- Chad J (5/5) Nov 15 2009 So, switch-case statements are a frequent source of nasty bugs. Fixing
- Andrei Alexandrescu (8/15) Nov 15 2009 I wish very much that a transferring control flow statement (break,
- Michel Fortin (35/37) Nov 15 2009 Hum two suggestions. Sometime I want fall-through when I write a
- Walter Bright (13/28) Nov 15 2009 I just use whitespace:
- bearophile (4/19) Nov 15 2009 If that's a try at something humorous I don't get it.
- Andrei Alexandrescu (7/39) Nov 15 2009 No whitespace works fine, too. I strongly advise requiring control flow
- Chad J (12/16) Nov 15 2009 T_T
- Chad J (16/29) Nov 15 2009 or if you want it to look nicer, maybe introduce an arrow token:
- Chris Nicholson-Sauls (21/40) Nov 15 2009 For what its worth, in a (very domain specific) scripting language I've ...
- Walter Bright (3/6) Nov 15 2009 Using "continue" for that purpose would silently break a lot of existing...
- Don (33/49) Nov 15 2009 Walter definitely *thinks* he uses fall-through all of the time. BUT...
- Walter Bright (2/6) Nov 15 2009 Except that I cannot recall ever having a bug from leaving out a break <...
- bearophile (4/5) Nov 15 2009 Even if that's true, fall-through bugs are well know, documented even.
- Andrei Alexandrescu (3/11) Nov 15 2009 Link?
- bearophile (42/43) Nov 15 2009 If you do a search with Google with:
- Walter Bright (3/5) Nov 15 2009 That is the only one I checked, and it was not a case fall-through bug.
- bearophile (5/7) Nov 15 2009 Sorry...
- Andrei Alexandrescu (4/10) Nov 15 2009 I can. I'm not sure where that leaves us. Others - please add your
- Derek Parnell (9/11) Nov 15 2009 Once Euphoria had implemented the 'fallthru' statement, it was like a
- Ellery Newcomer (11/24) Nov 15 2009 Just did a quick scan of phobos1. Found 5 instances of fallthrough, not
- Walter Bright (6/21) Nov 15 2009 LOL! Looks like you got me there. It appears here:
- Leandro Lucarella (10/33) Nov 15 2009 Yes, you might get a good quality software when doing that, who wants
- Andrei Alexandrescu (3/28) Nov 16 2009 I was hoping the lesson learned would be to fix switch as was suggested.
- Walter Bright (6/7) Nov 16 2009 I checked, because it wasn't written in the way I usually write things,
- Andrei Alexandrescu (3/13) Nov 16 2009 So people are liable to make the mistake.
- Bill Baxter (18/33) Nov 16 2009 .
- KennyTM~ (20/53) Nov 16 2009 Since
- Bill Baxter (19/81) Nov 16 2009 nge
- bearophile (4/10) Nov 16 2009 If someone writes a switch case so complex that the compiler isn't able ...
- KennyTM~ (4/91) Nov 16 2009 throw ...;
- Ellery Newcomer (2/91) Nov 16 2009 you can call functions which do these...
- Andrei Alexandrescu (3/85) Nov 16 2009 ... which is where the "none"/"bottom" type comes into play!
- Ellery Newcomer (2/13) Nov 16 2009 What what?
- Andrei Alexandrescu (7/19) Nov 16 2009 http://en.wikipedia.org/wiki/Bottom_type
- Ellery Newcomer (3/27) Nov 16 2009 So a function that always throws should have a result type (maximal
- Andrei Alexandrescu (4/30) Nov 16 2009 Yah, because it never actually returns. Functions like abort() or exit()...
- Andrei Alexandrescu (8/88) Nov 16 2009 It could enter difficult territory if the rule was:
- Andrei Alexandrescu (3/36) Nov 16 2009 You must pick the median :o).
- KennyTM~ (2/41) Nov 16 2009 No way we'll need to write "goto case 3.5;" :p
- Andrei Alexandrescu (4/49) Nov 16 2009 (Just for precision's sake)
- Steven Schveighoffer (4/12) Nov 16 2009 You're mean!
- KennyTM~ (2/51) Nov 16 2009 The median of [1,3,4,10000] is 3.5.
- Michel Fortin (16/25) Nov 15 2009 I did not get my habit of adding a "// fallthrough" comment because
- Bill Baxter (7/19) Nov 15 2009 I have without a doubt forgotten a "break". Many times. Last one was
- Max Samukha (5/15) Nov 16 2009 I used to introduce bugs by leaving out 'break'. So I had to fall into
- Chad J (3/9) Nov 15 2009 That's because you're a cyborg.
- Bill Baxter (5/14) Nov 15 2009 Yeh, you have to wondoer, is the goal to write a language that's
- Leandro Lucarella (10/17) Nov 15 2009 A lot of people do.
- bearophile (7/15) Nov 15 2009 In D this is the right way to write that:
- Andrei Alexandrescu (7/64) Nov 15 2009 Don <---------- genius
- Don (13/46) Nov 16 2009 Nah, I just know how Walter's mind works. It takes one to know one...
- Walter Bright (6/10) Nov 16 2009 I poked through the optimizer code, gloop.c and gflow.c, and right away
- Don (29/37) Nov 16 2009 You're right, there's one at the top of gloop. And this one in gflow is
- bearophile (4/6) Nov 16 2009 I don't understand that piece of code, is that valid code? It needs a re...
- Walter Bright (9/11) Nov 16 2009 I think it's more the #if that obfuscates the code. After long
- Steven Schveighoffer (19/25) Nov 16 2009 It hasn't hurt C# at all...
- Andrei Alexandrescu (7/38) Nov 16 2009 My thoughts exactly. But that being said, if a guy can't design his own
- Steven Schveighoffer (4/35) Nov 16 2009 You are totally free to make a language that nobody uses :)
- Walter Bright (48/49) Nov 16 2009 About 10 years ago, I went out jogging with a colleague who was also a
- grauzone (2/6) Nov 16 2009 D has no tuples.
- Chris Nicholson-Sauls (2/9) Nov 16 2009 I see what you did there.
- grauzone (5/12) Nov 15 2009 The correct way to solve this is to create a new switch-case statement
- bearophile (4/6) Nov 15 2009 We can add a third type of switch to D, that's safer...
- KennyTM~ (2/8) Nov 15 2009 @safe switch ? :p
- bearophile (4/5) Nov 15 2009 That's cute. But I was thinking of a safer "caseof" used by default, and...
- Derek Parnell (64/70) Nov 15 2009 And in spite of your good intentions (~ not a discussion ~) this will be
- MIURA Masahiro (4/7) Nov 16 2009 If I remember correctly, one of D's design policies is
- Denis Koroskin (5/13) Nov 16 2009 Correction: either behave like C, or raise a compile-time error.
- MIURA Masahiro (11/17) Nov 16 2009 Could you clarify? In you proposal, does a break statement
- Denis Koroskin (7/24) Nov 16 2009 Either I don't know C, or it breaks the switch, not the for-loop. In bot...
- MIURA Masahiro (2/4) Nov 16 2009 Arrrgh, please don't mind. My mistake. I'm sorry.
- KennyTM~ (15/32) Nov 16 2009 switch (x) {
- MIURA Masahiro (2/3) Nov 16 2009 Yes that's right. My mistake.
- bearophile (7/19) Nov 16 2009 Nice idea.
- Denis Koroskin (7/15) Nov 16 2009 It is a good policy to follow but there are cases where C behavior may
- bearophile (10/12) Nov 16 2009 What's bad about forcing people to write:
- Justin Johansson (10/26) Nov 16 2009 I don't know about "forcing people" to write such but perhaps it could
- Denis Koroskin (2/25) Nov 16 2009 Wow, this definitely needs to be bug-reported!
- Justin Johansson (3/36) Nov 16 2009 Wilco.
- grauzone (2/33) Nov 16 2009
- Don (5/21) Nov 16 2009 (1) "case A, B, C:" implies a relationship between A, B, and C, which
- bearophile (21/27) Nov 16 2009 It's just a list of things, it's a syntax people adapts too. Here too th...
- Justin Johansson (5/51) Nov 16 2009 So your use of the word "forcing" was quite intentional?
- Derek Parnell (17/39) Nov 16 2009 (1) case A:
- Denis Koroskin (47/83) Nov 16 2009 When porting some C++ code to D (okay, it was DMDFE), I had exact same
- Walter Bright (2/26) Nov 16 2009 I like that. Great suggestion!
- Don (4/32) Nov 17 2009 Yes, of course! In which situation, you use case A, B, C:
- Derek Parnell (7/8) Nov 17 2009 I apologize. I also don't know what I said to offend you. I've taken st...
- Sean Kelly (3/19) Nov 16 2009 As long as it's possible to enumerate a list of matches for one case sta...
So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)
Nov 15 2009
Chad J wrote:So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)I wish very much that a transferring control flow statement (break, return, goto etc.) is required at the end of each case. Then, the rare case when you want to break through is easy to implement as goto case xxx; and all is good. Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it. Andrei
Nov 15 2009
On 2009-11-15 12:54:02 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.Hum two suggestions. Sometime I want fall-through when I write a switch, but I always make it clear that it isn't a bug by writing the intent in a short comment: switch (c) { case 1: blah(); break; case 2: blah(); // fallthrough case 3: blah(); break; } That way I can always tell when I read again the code wether this was intentional or not. It wouldn't hurt at all if that "fallthrough" comment became a keyword: switch (c) { case 1: blah(); break; case 2: blah(); fallthrough; case 3: blah(); break; } Now the intent is clear even for the compiler. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 15 2009
Michel Fortin wrote:Hum two suggestions. Sometime I want fall-through when I write a switch, but I always make it clear that it isn't a bug by writing the intent in a short comment: switch (c) { case 1: blah(); break; case 2: blah(); // fallthrough case 3: blah(); break; }I just use whitespace: switch (c) { case 1: blah(); break; case 2: blah(); case 3: blah(); break; } Works fine.
Nov 15 2009
Walter Bright:I just use whitespace: switch (c) { case 1: blah(); break; case 2: blah(); case 3: blah(); break; } Works fine.If that's a try at something humorous I don't get it. Bye, bearophile
Nov 15 2009
Walter Bright wrote:Michel Fortin wrote:No whitespace works fine, too. I strongly advise requiring control flow at the end of the break. Your style notwithstanding, fall through *is* rare. It is also more brittle than goto case xxx; because it is not invariant to manual code motion. It does make sense to write more to achieve the more dangerous and less used result, than the other way around. AndreiHum two suggestions. Sometime I want fall-through when I write a switch, but I always make it clear that it isn't a bug by writing the intent in a short comment: switch (c) { case 1: blah(); break; case 2: blah(); // fallthrough case 3: blah(); break; }I just use whitespace: switch (c) { case 1: blah(); break; case 2: blah(); case 3: blah(); break; } Works fine.
Nov 15 2009
Andrei Alexandrescu wrote:Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.T_T There has to be a better way to do fall-through. Maybe... switch(foo) { case 0; case 1; bar = baz; // Executed if foo == 0 case 2: doSomething(bar); // Executed for foo ∈ {0,1,2} break; //required for compile success. }
Nov 15 2009
Chad J wrote:There has to be a better way to do fall-through. Maybe... switch(foo) { case 0; case 1; bar = baz; // Executed if foo == 0 case 2: doSomething(bar); // Executed for foo ∈ {0,1,2} break; //required for compile success. }or if you want it to look nicer, maybe introduce an arrow token: switch(foo) { case 0 -> case 1 -> bar = baz; // Executed if foo == 0 case 2: doSomething(bar); // Executed for foo ∈ {0,1,2} break; //required for compile success. } It has these advantages: * Fall-through behavior is explicit. * Fall-through notation requires no extra lines of source, and only a couple extra columns. Sigh, I didn't want to discuss syntax, but that response... it makes me want to solve problems, to say the least.
Nov 15 2009
Andrei Alexandrescu wrote:Chad J wrote:For what its worth, in a (very domain specific) scripting language I've been working on, I used 'continue' to implement fall-through, and haven't felt too bad about it. That and being able to do (case A, B, C:) helps for the most common (IME) sort of use. ////////////////////////////////////////////////// .__receive system ( cmd: STR, params ) switch ( cmd .lowercase .tosym ) case 'lo', 'login': user.tell( "(LOgin has been deprecated; please start using COnnect instead.)") continue; case 'co', 'connect': uname, pwd <- params; who = #Database::User.lookup( uname ) if ( who.valid && who.accept_password( pwd ) ) return .accept( user, who ); end // ... and so on ... end end ////////////////////////////////////////////////// -- Chris Nicholson-SaulsSo, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)I wish very much that a transferring control flow statement (break, return, goto etc.) is required at the end of each case. Then, the rare case when you want to break through is easy to implement as goto case xxx; and all is good. Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it. Andrei
Nov 15 2009
Chris Nicholson-Sauls wrote:For what its worth, in a (very domain specific) scripting language I've been working on, I used 'continue' to implement fall-through, and haven't felt too bad about it.Using "continue" for that purpose would silently break a lot of existing code.
Nov 15 2009
Andrei Alexandrescu wrote:Chad J wrote:Walter definitely *thinks* he uses fall-through all of the time. BUT... Does he *really* use it all the time? It's not a matter of opinion; it's an objective question, answerable since so much of his code is now publically available. I got a bit interested in knowing how much he does use it. I consider that fallthrough requires a non-empty statement. IE, case A: case B: case C: dosomething(); break; is not a real fallthrough; those would always be allowed. I looked through a couple of DMD files: parse.c, (the parser), and cod3.c (the largest file in the back-end). In cod3, there are 381 case statements. There are 3 occasions where fallthrough is used. In two of those cases, they fallthrough to a label where other cases have 'goto' that label. In the remaining case, the code which was fallen through was an assert and a debug print statement. parse.c has 541 case statements, I didn't find any fallthroughs in the first half of the code, but I didn't look as thoroughly as I did in cod3. Based on this, it looks to me as though Walter uses fall-through very, very rarely. Less than 1% of all case statements. For comparison, those files contain 178 and 137 gotos, respectively <g>. Walter does use 'goto'. He doesn't use fallthrough in switch statements. It's actually not something I care about at all. But I think Walter's wrong about his coding style. And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement. An interesting result. But I'd much rather change Walter's mind about opPow() or the meta.compiles(XXX) proposal.So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)I wish very much that a transferring control flow statement (break, return, goto etc.) is required at the end of each case. Then, the rare case when you want to break through is easy to implement as goto case xxx; and all is good. Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.
Nov 15 2009
Don wrote:And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
Walter Bright:Except that I cannot recall ever having a bug from leaving out a break <g>.Even if that's true, fall-through bugs are well know, documented even. Bye, bearophile
Nov 15 2009
bearophile wrote:Walter Bright:Link? AndreiExcept that I cannot recall ever having a bug from leaving out a break <g>.Even if that's true, fall-through bugs are well know, documented even. Bye, bearophile
Nov 15 2009
Andrei AlexandrescuLink?If you do a search with Google with: switch bug "missing break" Or: switch bug "fall through" Or: switch most common programming bugs You will see a ton of pages. Wikipedia says this is a common bug: http://en.wikipedia.org/wiki/Switch_statement A bug in Python: http://bugs.python.org/issue4772 Gcj: http://gcc.gnu.org/ml/java/2001-12/msg00153.html Page on C++ pitfalls: http://www.gauravcreations.com/tutorials/c_pitfalls.html It's error 825 on Gimpel: http://www.gimpel.com/html/pub90/msg.txt Ona page of common C bugs: Another in Gcc: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31137 More: http://pear.php.net/bugs/bug.php?id=5020 http://sourceware.org/ml/gdb-patches/2006-04/msg00234.html https://savannah.cern.ch/bugs/?15576 http://aspn.activestate.com/ASPN/Mail/Message/php-Dev/901756 http://opensource.atlassian.com/projects/hibernate/browse/HHH-448 A page that warns again them: http://www.jaggersoft.com/pubs/CVu09_1.html Listed by Linus: http://lkml.org/lkml/2005/9/30/219 Java findbugs is supposed to find them: http://osdir.com/ml/java.findbugs.general/2005-01/msg00020.html In boost: http://www.boost.org/doc/tools/jam/jam/history.html If you keep searching you can find a good amount of them. It's not the most common kind of bug, but it seems common enough to deserve warnings, lints, several pages of "C/C++ traps & tricks", etc. There is also a well know bug by AT&T, but it's a little different: http://www.gowrikumar.com/blog/2009/01/06/att-break-bug/ Bye, bearophile
Nov 15 2009
bearophile wrote:A bug in Python: http://bugs.python.org/issue4772That is the only one I checked, and it was not a case fall-through bug. It was failure to provide a default.
Nov 15 2009
Walter Bright:That is the only one I checked, and it was not a case fall-through bug. It was failure to provide a default.Sorry... Most of those bugs seem about the missing break, but indeed it seems that the missing default is an even more common bug, that's why I have said "It's not the most common bug". Bye, bearophile
Nov 15 2009
Walter Bright wrote:Don wrote:I can. I'm not sure where that leaves us. Others - please add your experience. AndreiAnd looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
On Sun, 15 Nov 2009 15:03:39 -0600, Andrei Alexandrescu wrote:I'm not sure where that leaves us. Others - please add your experience.Once Euphoria had implemented the 'fallthru' statement, it was like a weight lifted from the code. It just looked better and was far easier to write code. A small change, but an wonderfully liberating change. A bit like the effect of using [$] rather than [length]. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Nov 15 2009
Andrei Alexandrescu wrote:Walter Bright wrote:Just did a quick scan of phobos1. Found 5 instances of fallthrough, not including one around line 182, format.d case Mangle.Tdchar: ti = typeid(dchar); default: ti = null; I have a hard time believing that was intentional, although it as near as I can tell it will never be executed. "Written by Walter Bright" hm.Don wrote:I can. I'm not sure where that leaves us. Others - please add your experience. AndreiAnd looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
Ellery Newcomer wrote:Just did a quick scan of phobos1. Found 5 instances of fallthrough, not including one around line 182, format.d case Mangle.Tdchar: ti = typeid(dchar); default: ti = null; I have a hard time believing that was intentional, although it as near as I can tell it will never be executed. "Written by Walter Bright" hm.LOL! Looks like you got me there. It appears here: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/format.d?rev=132 in the first version of that switch statement. I'll check in a fix. Lesson learned: Never open source your software! <g>
Nov 15 2009
Walter Bright, el 15 de noviembre a las 18:10 me escribiste:Ellery Newcomer wrote:Yes, you might get a good quality software when doing that, who wants that!? =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- I am so psychosomatic it makes me sick just thinking about it! -- George ConstanzaJust did a quick scan of phobos1. Found 5 instances of fallthrough, not including one around line 182, format.d case Mangle.Tdchar: ti = typeid(dchar); default: ti = null; I have a hard time believing that was intentional, although it as near as I can tell it will never be executed. "Written by Walter Bright" hm.LOL! Looks like you got me there. It appears here: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/format.d?rev=132 in the first version of that switch statement. I'll check in a fix. Lesson learned: Never open source your software! <g>
Nov 15 2009
Walter Bright wrote:Ellery Newcomer wrote:I was hoping the lesson learned would be to fix switch as was suggested. AndreiJust did a quick scan of phobos1. Found 5 instances of fallthrough, not including one around line 182, format.d case Mangle.Tdchar: ti = typeid(dchar); default: ti = null; I have a hard time believing that was intentional, although it as near as I can tell it will never be executed. "Written by Walter Bright" hm.LOL! Looks like you got me there. It appears here: http://www.dsource.org/projects/phobos/browser/trunk/phobos/ td/format.d?rev=132 in the first version of that switch statement. I'll check in a fix. Lesson learned: Never open source your software! <g>
Nov 16 2009
Andrei Alexandrescu wrote:I was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
Walter Bright wrote:Andrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Walter Bright wrote:.Andrei Alexandrescu wrote:I was hoping the lesson learned would be to fix switch as was suggested=rmatI checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) =A0From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.fo=What about when you want to fall through to a multiple label? Or a range l= abel? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbwhich can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129So people are liable to make the mistake. Andrei
Nov 16 2009
On Nov 17, 09 01:12, Bill Baxter wrote:On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Since case a: .. case b: expands to case a: case a+1: case a+2: // .... case b: and case a,b,c,d: expands to case a: case b: case c: case d: Your speculation is correct. Please note that the "goto case X;" statement works *now*, so there's no need to guess its behavior.Walter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
On Mon, Nov 16, 2009 at 9:30 AM, KennyTM~ <kennytm gmail.com> wrote:On Nov 17, 09 01:12, Bill Baxter wrote:,On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> =A0wrote:Walter Bright wrote:Andrei Alexandrescu wrote:I was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things=ngeWhat about when you want to fall through to a multiple label? =A0Or a ra=and sure enough it wasn't code I wrote :-) =A0From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129So people are liable to make the mistake. Andreitlabel? case 0: =A0 =A0 // do stuff =A0 =A0 goto case ??; case 1: .. case 9: =A0 =A0 =A0// do more stuff =A0 =A0 =A0goto case ??; case 10,20,30: =A0 =A0 =A0// still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbSince case a: .. case b: expands to case a: case a+1: case a+2: // .... case b: and case a,b,c,d: expands to case a: case b: case c: case d: Your speculation is correct. Please note that the "goto case X;" statemen=works *now*, so there's no need to guess its behavior.Seriously? Didn't realize. So valid end-of-case statements would be: break; return; continue; goto *; goto case *; And if you don't have one of those then it's an error? Could this get into difficult-to-verify territory? And therefore be difficult to implement? It looks like the exact same problem as enforcing that all code paths return a value, which is something I think D doesn't currently enforce because it's too hard. So you run into Walter's dislike for errors/warnings that are incorrect because the compiler is too stupid. --bb
Nov 16 2009
Bill Baxter:Could this get into difficult-to-verify territory? And therefore be difficult to implement? It looks like the exact same problem as enforcing that all code paths return a value, which is something I think D doesn't currently enforce because it's too hard. So you run into Walter's dislike for errors/warnings that are incorrect because the compiler is too stupid.If someone writes a switch case so complex that the compiler isn't able to understand if it's a fall-through or not, then that's a sign that the code needs to be improved/simplified :-) Bye, bearophile
Nov 16 2009
On Nov 17, 09 01:48, Bill Baxter wrote:On Mon, Nov 16, 2009 at 9:30 AM, KennyTM~<kennytm gmail.com> wrote:throw ...; assert(...);On Nov 17, 09 01:12, Bill Baxter wrote:Seriously? Didn't realize. So valid end-of-case statements would be: break; return; continue; goto *; goto case *;On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Since case a: .. case b: expands to case a: case a+1: case a+2: // .... case b: and case a,b,c,d: expands to case a: case b: case c: case d: Your speculation is correct. Please note that the "goto case X;" statement works *now*, so there's no need to guess its behavior.Walter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129And if you don't have one of those then it's an error? Could this get into difficult-to-verify territory? And therefore be difficult to implement? It looks like the exact same problem as enforcing that all code paths return a value, which is something I think D doesn't currently enforce because it's too hard. So you run into Walter's dislike for errors/warnings that are incorrect because the compiler is too stupid. --bbBut DMD already has the "no return at end of function" warning.
Nov 16 2009
KennyTM~ wrote:On Nov 17, 09 01:48, Bill Baxter wrote:you can call functions which do these...On Mon, Nov 16, 2009 at 9:30 AM, KennyTM~<kennytm gmail.com> wrote:throw ...; assert(...);On Nov 17, 09 01:12, Bill Baxter wrote:Seriously? Didn't realize. So valid end-of-case statements would be: break; return; continue; goto *; goto case *;On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Since case a: .. case b: expands to case a: case a+1: case a+2: // .... case b: and case a,b,c,d: expands to case a: case b: case c: case d: Your speculation is correct. Please note that the "goto case X;" statement works *now*, so there's no need to guess its behavior.Walter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
Ellery Newcomer wrote:KennyTM~ wrote:... which is where the "none"/"bottom" type comes into play! AndreiOn Nov 17, 09 01:48, Bill Baxter wrote:you can call functions which do these...On Mon, Nov 16, 2009 at 9:30 AM, KennyTM~<kennytm gmail.com> wrote:throw ...; assert(...);On Nov 17, 09 01:12, Bill Baxter wrote:Seriously? Didn't realize. So valid end-of-case statements would be: break; return; continue; goto *; goto case *;On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Since case a: .. case b: expands to case a: case a+1: case a+2: // .... case b: and case a,b,c,d: expands to case a: case b: case c: case d: Your speculation is correct. Please note that the "goto case X;" statement works *now*, so there's no need to guess its behavior.Walter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
Andrei Alexandrescu wrote:Ellery Newcomer wrote:What what?KennyTM~ wrote:... which is where the "none"/"bottom" type comes into play! Andreithrow ...; assert(...);you can call functions which do these...
Nov 16 2009
Ellery Newcomer wrote:Andrei Alexandrescu wrote:http://en.wikipedia.org/wiki/Bottom_type http://www.cs.washington.edu/research/projects/cecil/www/Release/doc-cecil-stdlib/node4.html I gave a talk about similar stuff once but I don't know where it is. I also have 70% of an article on it written (and with a funny introduction to boot) but I couldn't find the time * interest to finish. AndreiEllery Newcomer wrote:What what?KennyTM~ wrote:... which is where the "none"/"bottom" type comes into play! Andreithrow ...; assert(...);you can call functions which do these...
Nov 16 2009
Andrei Alexandrescu wrote:Ellery Newcomer wrote:So a function that always throws should have a result type (maximal type?) of bottom type?Andrei Alexandrescu wrote:http://en.wikipedia.org/wiki/Bottom_type http://www.cs.washington.edu/research/projects/cecil/www/Release/doc-cecil-stdlib/node4.html I gave a talk about similar stuff once but I don't know where it is. I also have 70% of an article on it written (and with a funny introduction to boot) but I couldn't find the time * interest to finish. AndreiEllery Newcomer wrote:What what?KennyTM~ wrote:... which is where the "none"/"bottom" type comes into play! Andreithrow ...; assert(...);you can call functions which do these...
Nov 16 2009
Ellery Newcomer wrote:Andrei Alexandrescu wrote:Yah, because it never actually returns. Functions like abort() or exit() would return bottom in a type system that supports it. AndreiEllery Newcomer wrote:So a function that always throws should have a result type (maximal type?) of bottom type?Andrei Alexandrescu wrote:http://en.wikipedia.org/wiki/Bottom_type http://www.cs.washington.edu/research/projects/cecil/www/Release/doc-cecil-stdlib/node4.html I gave a talk about similar stuff once but I don't know where it is. I also have 70% of an article on it written (and with a funny introduction to boot) but I couldn't find the time * interest to finish. AndreiEllery Newcomer wrote:What what?KennyTM~ wrote:... which is where the "none"/"bottom" type comes into play! Andreithrow ...; assert(...);you can call functions which do these...
Nov 16 2009
Bill Baxter wrote:On Mon, Nov 16, 2009 at 9:30 AM, KennyTM~ <kennytm gmail.com> wrote:throw *;On Nov 17, 09 01:12, Bill Baxter wrote:Seriously? Didn't realize. So valid end-of-case statements would be: break; return; continue; goto *; goto case *; And if you don't have one of those then it's an error?On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Since case a: .. case b: expands to case a: case a+1: case a+2: // .... case b: and case a,b,c,d: expands to case a: case b: case c: case d: Your speculation is correct. Please note that the "goto case X;" statement works *now*, so there's no need to guess its behavior.Walter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129Could this get into difficult-to-verify territory? And therefore be difficult to implement? It looks like the exact same problem as enforcing that all code paths return a value, which is something I think D doesn't currently enforce because it's too hard. So you run into Walter's dislike for errors/warnings that are incorrect because the compiler is too stupid.It could enter difficult territory if the rule was: if (condition) break; and leave it to the compiler to prove that condition is always true. That's not the case with the proposed change. All control flow statements you enumerated above transfer flow unconditionally. Andrei
Nov 16 2009
Bill Baxter wrote:On Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:You must pick the median :o). AndreiWalter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
On Nov 17, 09 01:40, Andrei Alexandrescu wrote:Bill Baxter wrote:No way we'll need to write "goto case 3.5;" :pOn Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:You must pick the median :o). AndreiWalter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
KennyTM~ wrote:On Nov 17, 09 01:40, Andrei Alexandrescu wrote:(Just for precision's sake) median != average AndreiBill Baxter wrote:No way we'll need to write "goto case 3.5;" :pOn Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:You must pick the median :o). AndreiWalter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
On Mon, 16 Nov 2009 13:37:52 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:KennyTM~ wrote:You're mean! -SteveOn Nov 17, 09 01:40, Andrei Alexandrescu wrote:(Just for precision's sake) median != averageYou must pick the median :o). AndreiNo way we'll need to write "goto case 3.5;" :p
Nov 16 2009
On Nov 17, 09 02:37, Andrei Alexandrescu wrote:KennyTM~ wrote:The median of [1,3,4,10000] is 3.5.On Nov 17, 09 01:40, Andrei Alexandrescu wrote:(Just for precision's sake) median != average AndreiBill Baxter wrote:No way we'll need to write "goto case 3.5;" :pOn Mon, Nov 16, 2009 at 8:24 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:You must pick the median :o). AndreiWalter Bright wrote:What about when you want to fall through to a multiple label? Or a range label? case 0: // do stuff goto case ??; case 1: .. case 9: // do more stuff goto case ??; case 10,20,30: // still more stuff The obvious answer would seem to be just "pick any one". I just bring it up because I haven't seen that ... uh case ... mentioned by anyone. --bbAndrei Alexandrescu wrote:So people are liable to make the mistake. AndreiI was hoping the lesson learned would be to fix switch as was suggested.I checked, because it wasn't written in the way I usually write things, and sure enough it wasn't code I wrote :-) From the changelog for D 0.129: "Incorporated Ben Hinkle's new std.format which can print general arrays." http://www.digitalmars.com/d/1.0/changelog1.html#new0129
Nov 16 2009
On 2009-11-15 16:03:39 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Walter Bright wrote:I did not get my habit of adding a "// fallthrough" comment because someone told me I should. It was after experiencing too many "forgotten break" bugs that I began to do this so that now if I read some of my code that doesn't explicitly mention it wants falltrhough, it looks immeditately suspicious. Thus, it helps detecting bugs earlier. Apparently, Walter's whitespace convention accomplish the same goal. I wonder from where it comes... Most of those missing break bugs I catch early when debugging or reviewing, but that is still needlessly time-consuming considering it'd be pretty simple for the compiler to make sure everything is all right. -- Michel Fortin michel.fortin michelf.com http://michelf.com/Don wrote:I can. I'm not sure where that leaves us. Others - please add your experience.And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
On Sun, Nov 15, 2009 at 1:03 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Walter Bright wrote:I have without a doubt forgotten a "break". Many times. Last one was probably just a week or two ago. Of course now after years of C and C++, I'm more attuned to it, so it didn't take that long to figure out where the bug is. But still it's annoying. --bbDon wrote:I can. I'm not sure where that leaves us. Others - please add your experience.And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
On Sun, 15 Nov 2009 15:03:39 -0600, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Walter Bright wrote:I used to introduce bugs by leaving out 'break'. So I had to fall into habit of writing 'break' before adding other code to a case block. Fall-through should be explicit.Don wrote:I can. I'm not sure where that leaves us. Others - please add your experience. AndreiAnd looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 16 2009
Walter Bright wrote:Don wrote:That's because you're a cyborg. Have some pity on us mere mortals ;)And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
On Sun, Nov 15, 2009 at 1:16 PM, Chad J <chadjoan __spam.is.bad__gmail.com> wrote:Walter Bright wrote:Yeh, you have to wondoer, is the goal to write a language that's perfect for yourself or perfect for the widest audience possible? --bbDon wrote:That's because you're a cyborg. Have some pity on us mere mortals ;)And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
Walter Bright, el 15 de noviembre a las 12:13 me escribiste:Don wrote:A lot of people do. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Yo soy peperino el que siempre pone el vino, yo soy aquel que come los huevos con tocino. -- Peperino PómoroAnd looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement.Except that I cannot recall ever having a bug from leaving out a break <g>.
Nov 15 2009
Don:I consider that fallthrough requires a non-empty statement. IE, case A: case B: case C: dosomething(); break; is not a real fallthrough; those would always be allowed.In D this is the right way to write that: case A, B, C: dosomething(); break; Bye, bearophile
Nov 15 2009
Don wrote:Andrei Alexandrescu wrote:Don <---------- genius I understand that you're more interested about the issues that preoccupy you (and incidentally me) the most, but "switch" is a day-to-day programming (and programmer's) workhorse, so a change there might have a wider (and hopefully more positive) impact. AndreiChad J wrote:Walter definitely *thinks* he uses fall-through all of the time. BUT... Does he *really* use it all the time? It's not a matter of opinion; it's an objective question, answerable since so much of his code is now publically available. I got a bit interested in knowing how much he does use it. I consider that fallthrough requires a non-empty statement. IE, case A: case B: case C: dosomething(); break; is not a real fallthrough; those would always be allowed. I looked through a couple of DMD files: parse.c, (the parser), and cod3.c (the largest file in the back-end). In cod3, there are 381 case statements. There are 3 occasions where fallthrough is used. In two of those cases, they fallthrough to a label where other cases have 'goto' that label. In the remaining case, the code which was fallen through was an assert and a debug print statement. parse.c has 541 case statements, I didn't find any fallthroughs in the first half of the code, but I didn't look as thoroughly as I did in cod3. Based on this, it looks to me as though Walter uses fall-through very, very rarely. Less than 1% of all case statements. For comparison, those files contain 178 and 137 gotos, respectively <g>. Walter does use 'goto'. He doesn't use fallthrough in switch statements. It's actually not something I care about at all. But I think Walter's wrong about his coding style. And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement. An interesting result. But I'd much rather change Walter's mind about opPow() or the meta.compiles(XXX) proposal.So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)I wish very much that a transferring control flow statement (break, return, goto etc.) is required at the end of each case. Then, the rare case when you want to break through is easy to implement as goto case xxx; and all is good. Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.
Nov 15 2009
Andrei Alexandrescu wrote:Don wrote:Andrei Alexandrescu wrote:Chad J wrote:So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.Nah, I just know how Walter's mind works. It takes one to know one... I frequently use fall-through myself, but having looked at this sample, I bet I don't use it nearly as much as I thought: again, "frequently" probably means "about 1% of the time". But I *know* I've had bugs from leaving out 'break'.It's actually not something I care about at all. But I think Walter's wrong about his coding style. And looking at how rarely it's actually used by someone who thinks he uses it a lot, convinces me that intentional use of fall-through is much less common than bugs introduced by leaving out a break statement. An interesting result. But I'd much rather change Walter's mind about opPow() or the meta.compiles(XXX) proposal.Don <---------- geniusI understand that you're more interested about the issues that preoccupy you (and incidentally me) the most, but "switch" is a day-to-day programming (and programmer's) workhorse, so a change there might have a wider (and hopefully more positive) impact.I should have said "immutable array literals" instead.Requiring 'goto' to implement fall-through would run into the prejudice against 'goto'. It's necessary to persuade managers that "goto case XXX;" isn't a bad, evil goto that eats babies. I have no idea if that's difficult or not. Otherwise, I think it's a superb solution. (providing that empty fall-through case statements remain valid; disallowing them would be really annoying).I wish very much that a transferring control flow statement (break, return, goto etc.) is required at the end of each case. Then, the rare case when you want to break through is easy to implement as goto case xxx; and all is good.
Nov 16 2009
Don wrote:I frequently use fall-through myself, but having looked at this sample, I bet I don't use it nearly as much as I thought: again, "frequently" probably means "about 1% of the time". But I *know* I've had bugs from leaving out 'break'.I poked through the optimizer code, gloop.c and gflow.c, and right away saw several uses of it. I used to mark these with /* FALL-THROUGH */, but eventually got tired of that (and thought it was ugly) and just switched to using whitespace as I mentioned before.
Nov 16 2009
Walter Bright wrote:Don wrote:You're right, there's one at the top of gloop. And this one in gflow is a doozy. case OPvptrfptr: case OPcvptrfptr: if ((flowxx == AE) && n->Eexp) vec_orass(KILL,vptrkill); break; default: if (OTunary(op)) { #if TX86 case OPind: // most common unary operator accumaecpx(n->E1); #ifdef DEBUG assert(!OTassign(op)); #endif #else accumaecpx(n->E1); if (OTassign(op)) t = Elvalue(n); #endif } else if (OTbinary(op)) { if (OTrtol(op) && ERTOL(n)) { accumaecpx(n->E2); That's not fall-through, one case is *inside* the 'if' clause of another one!! Wow. Do you really want to encourage that sort of thing?I frequently use fall-through myself, but having looked at this sample, I bet I don't use it nearly as much as I thought: again, "frequently" probably means "about 1% of the time". But I *know* I've had bugs from leaving out 'break'.I poked through the optimizer code, gloop.c and gflow.c, and right away saw several uses of it.
Nov 16 2009
Don:That's not fall-through, one case is *inside* the 'if' clause of another one!! Wow. Do you really want to encourage that sort of thing?I don't understand that piece of code, is that valid code? It needs a reformatting, a rewriting, and then another reformatting. Bye, bearophile
Nov 16 2009
Don wrote:That's not fall-through, one case is *inside* the 'if' clause of another one!! Wow. Do you really want to encourage that sort of thing?I think it's more the #if that obfuscates the code. After long experience with #if, I really don't like it, which is why I adamantly resist having fine-grained conditional compilation in D. The optimizer/code generator has a lot of awful #if's in them, generally as a result of it being hackishly ported to other platforms. I'm not going to stand up and say the optimizer/code gen is a fine example of elegant software (it isn't), just that it *works* and is remarkably free of bugs.
Nov 16 2009
Walter Bright wrote:Don wrote:True, but the case label inside the if statement is obfuscation too. I bet many C/C++ programmers don't even know that this syntax is allowed... But we need to keep it for duff's device, I guess.That's not fall-through, one case is *inside* the 'if' clause of another one!! Wow. Do you really want to encourage that sort of thing?I think it's more the #if that obfuscates the code. After long experience with #if, I really don't like it, which is why I adamantly resist having fine-grained conditional compilation in D.
Nov 16 2009
Walter Bright wrote:Don wrote:I'm used to that. If you take out the #if, it's still wierd. That one really ought to be a goto. It's the presence of the 'else' in particular: case A: if (xxx) { case B: yyy; } else { zzz; } break; I had to read it several times before I could make sense of it. Although the zzz; looks like it's part of the B case, it's only part of the A case. An oddity is that this compiles: switch(x) { case 1: if (x<10) Lcase2: writefln("yyy"); else writefln("zzz"); break; } and so does this: switch(x) { case 1: if (x<10) case 2: writefln("yyy"); } but this doesn't: switch(x) { case 1: if (x<10) case 2: writefln("yyy"); else writefln("zzz"); break; }That's not fall-through, one case is *inside* the 'if' clause of another one!! Wow. Do you really want to encourage that sort of thing?I think it's more the #if that obfuscates the code. After long experience with #if, I really don't like it, which is why I adamantly resist having fine-grained conditional compilation in D.
Nov 17 2009
On Mon, 16 Nov 2009 03:27:22 -0500, Don <nospam nospam.com> wrote:Requiring 'goto' to implement fall-through would run into the prejudice against 'goto'. It's necessary to persuade managers that "goto case XXX;" isn't a bad, evil goto that eats babies. I have no idea if that's difficult or not. Otherwise, I think it's a superb solution. (providing that empty fall-through case statements remain valid; disallowing them would be really annoying).http://msdn.microsoft.com/en-us/library/06tc147t(VS.80).aspx I haven't had any issues with it. This reminds me of the != null problem. Now if only Walter made as many mistakes with switch case fallthrough as he did with != null :) Walter, at some point, you should heed the complaints of the masses even if it doesn't affect you. It's like a politician who lives in a nice neighborhood ignoring the requests of his constituents for more police protection in higher crime areas because he doesn't live there. Except it's worse, because we can't vote you out :) Also keep in mind that this does *not* change the power of switch at all, since goto already covers fallthrough. One thing I learned from the != null to !is null change is that I stopped writing the offending code when I get immediate feedback. It just gets ingrained in my brain better. So having to write goto next_case; all the time is going to be much less of a chore than you think, because you'll just learn to avoid that mistake in the first place. -Steve
Nov 16 2009
Steven Schveighoffer wrote:On Mon, 16 Nov 2009 03:27:22 -0500, Don <nospam nospam.com> wrote:My thoughts exactly. But that being said, if a guy can't design his own language to cater for what he thinks he frequently does (massive, overwhelming, and exhausting evidence to the contrary notwithstanding), then where is freedom in this world? :o) AndreiRequiring 'goto' to implement fall-through would run into the prejudice against 'goto'. It's necessary to persuade managers that "goto case XXX;" isn't a bad, evil goto that eats babies. I have no idea if that's difficult or not. Otherwise, I think it's a superb solution. (providing that empty fall-through case statements remain valid; disallowing them would be really annoying).http://msdn.microsoft.com/en-us/library/06tc147t(VS.80).aspx I haven't had any issues with it. This reminds me of the != null problem. Now if only Walter made as many mistakes with switch case fallthrough as he did with != null :) Walter, at some point, you should heed the complaints of the masses even if it doesn't affect you. It's like a politician who lives in a nice neighborhood ignoring the requests of his constituents for more police protection in higher crime areas because he doesn't live there. Except it's worse, because we can't vote you out :) Also keep in mind that this does *not* change the power of switch at all, since goto already covers fallthrough. One thing I learned from the != null to !is null change is that I stopped writing the offending code when I get immediate feedback. It just gets ingrained in my brain better. So having to write goto next_case; all the time is going to be much less of a chore than you think, because you'll just learn to avoid that mistake in the first place.
Nov 16 2009
On Mon, 16 Nov 2009 15:01:47 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:You are totally free to make a language that nobody uses :) -SteveOn Mon, 16 Nov 2009 03:27:22 -0500, Don <nospam nospam.com> wrote:My thoughts exactly. But that being said, if a guy can't design his own language to cater for what he thinks he frequently does (massive, overwhelming, and exhausting evidence to the contrary notwithstanding), then where is freedom in this world?Requiring 'goto' to implement fall-through would run into the prejudice against 'goto'. It's necessary to persuade managers that "goto case XXX;" isn't a bad, evil goto that eats babies. I have no idea if that's difficult or not. Otherwise, I think it's a superb solution. (providing that empty fall-through case statements remain valid; disallowing them would be really annoying).http://msdn.microsoft.com/en-us/library/06tc147t(VS.80).aspx I haven't had any issues with it. This reminds me of the != null problem. Now if only Walter made as many mistakes with switch case fallthrough as he did with != null :) Walter, at some point, you should heed the complaints of the masses even if it doesn't affect you. It's like a politician who lives in a nice neighborhood ignoring the requests of his constituents for more police protection in higher crime areas because he doesn't live there. Except it's worse, because we can't vote you out :) Also keep in mind that this does *not* change the power of switch at all, since goto already covers fallthrough. One thing I learned from the != null to !is null change is that I stopped writing the offending code when I get immediate feedback. It just gets ingrained in my brain better. So having to write goto next_case; all the time is going to be much less of a chore than you think, because you'll just learn to avoid that mistake in the first place.
Nov 16 2009
Steven Schveighoffer wrote:You are totally free to make a language that nobody uses :)About 10 years ago, I went out jogging with a colleague who was also a programmer. We were talking about compilers, of course, and he said "what the world really needs is a Java compiler that compiles to native code, not this VM bull." He assured me that such a product would sweep the world. I told him I thought he was right, and so did a lot of people. So right that about 5 years previously, I did just that (for Symantec). Turns out, nobody wanted it. I told him I could get him a copy. He didn't want it either. <g> Another fun story. Back in the 80's, a programmer told a friend that the MOST IMPORTANT thing he looked for in a compiler was compilation speed. My friend told him that was obviously the least important thing to him. Shocked, the programmer asked why? My friend told him that he was using the slowest compiler on the market by a factor of 4. There were several other much faster C++ compilers available, but he stuck with the slow one. The programmer reacted like this thought had never occurred to him. <g> More fun stuff. 10 years ago, I was convinced by many people that the world needed a fast javascript engine. I built one that was twice as fast as Jscript, and twenty (that's right, 20) times faster than Mozilla's javascript engine. It passed all the test suites. I couldn't give it away. On the other hand, the advice I got when starting to write a C compiler was "who the f*** needs another C compiler?" Nobody thought it was a good idea. Turns out, there was a big market for it! Now, I'm not saying you're wrong. I'm just saying that making a product that people want isn't as simple as asking them what they want. With the switch thing, there's a cost to all the solutions proposed here - rather klunky to look at and significant extra work to type them in. Perhaps the reason I don't have trouble with the usual switch statements is because it seems natural to me, as I come from an asm/fortran/basic background, where one would never write: foo(); goto L1; L1: bar(); goto L2; L2: baz(); goto L3; L3: asdf(); return; and case labels look like, well, labels to me. The goto version is ugly and hard to read. Reminds me a bit of D a few years back, when people would say D didn't have lambda's. But D did have them! The problem was the syntax was a bit verbose. Simplified the syntax, and suddenly the lambda's got noticed and got used.
Nov 16 2009
Walter Bright wrote:Reminds me a bit of D a few years back, when people would say D didn't have lambda's. But D did have them! The problem was the syntax was a bit verbose. Simplified the syntax, and suddenly the lambda's got noticed and got used.D has no tuples.
Nov 16 2009
grauzone wrote:Walter Bright wrote:I see what you did there.Reminds me a bit of D a few years back, when people would say D didn't have lambda's. But D did have them! The problem was the syntax was a bit verbose. Simplified the syntax, and suddenly the lambda's got noticed and got used.D has no tuples.
Nov 16 2009
Chad J wrote:So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)The correct way to solve this is to create a new switch-case statement that doesn't suck. It would use a different syntax, and support spiffy stuff like pattern matching. If you wanted to use duff's device or need C compatibility, you still could use the old switch-case.
Nov 15 2009
Andrei Alexandrescu:Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.We can add a third type of switch to D, that's safer... Bye, bearophile
Nov 15 2009
On Nov 16, 09 02:36, bearophile wrote:Andrei Alexandrescu:safe switch ? :pWalter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.We can add a third type of switch to D, that's safer... Bye, bearophile
Nov 15 2009
KennyTM~:safe switch ? :pThat's cute. But I was thinking of a safer "caseof" used by default, and the less safe C switch used only for C compatibility :-) (" unsafe switch" is not possible because it's against D purposes). Bye, bearophile
Nov 15 2009
On Sun, 15 Nov 2009 12:49:01 -0500, Chad J wrote:So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2?The phrase "snowball in hell" comes to mind.(This is intended as more of a reminder and simple curiosity than a discussion.)And in spite of your good intentions (~ not a discussion ~) this will be one ;-) The Euphoria Programming language, which I'm helping to implement, has 'solved' this issue. This language is not a C-derived one so don't be alarmed at its apparent verbosity. The default 'case' in a 'switch' is to not fall through; an implied 'break' is assumed at the end of each 'case' clause. switch Foo do case 1 then ... whatever for 1 ... ... does not fall through to the next case ... case 2, 3 then ... whatever for 2 and 3 ... ... does not fall through to the next case ... case 4 then ... whatever for 4 ... ... does not fall through to the next case ... end switch However, the coder can change the default behaviour on a 'switch' statement by including the phrase 'with fallthru', thus changing the default behaviour such that each 'case' clause will fall through to the next case unless the coder uses an explicit 'break' statement. This, as you can see, is the DPL behaviour. switch Foo with fallthru do case 1 then ... whatever for 1 ... ... falls through to the next case ... case 2, 3 then ... whatever for 2 and 3 ... break /* explicitly required to prevent falling through */ case 4 then ... whatever for 4 ... ... falls through to the next case ... end switch Further more, whatever the default behaviour for the 'switch', it can be adjusted on any of the 'case' clauses. This means that a by-default-break switch, can use the 'fallthru' statement to explicitly override the break default and fall through to the next case. switch Foo do /* by default, break */ case 1 then ... whatever for 1 ... fallthru /* explicitly falls through */ case 2, 3 then ... whatever for 2 and 3 ... ... implied break here ... case 4 then ... whatever for 4 ... ... implied break here ... end switch In short, Euphoria allows for both ideologies to exist, and in fact to co-exist in peace. The standard default gives most protection from mistakes, but for those coders that like to keep on the edge, they can code with the level of risk that is acceptable to themselves. I can see good reason for DPL to adopt a similar stance. I would suggest a new keyword to make things easier for coders (after all, that's why we have programming languages), but for those who see keywords as evil, I'm sure that someone can come up with another syntax that avoids a new keyword (at the expense of clarity) eg. "! break" or the old standby, "static" LOL. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Nov 15 2009
On 11/16/2009 02:49 AM, Chad J wrote:So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2?If I remember correctly, one of D's design policies is that a D code that looks like C code should behave like C. Are we giving up that policy?
Nov 16 2009
On Mon, 16 Nov 2009 11:58:44 +0300, MIURA Masahiro <echochamber gmail.com> wrote:On 11/16/2009 02:49 AM, Chad J wrote:Correction: either behave like C, or raise a compile-time error. Missing break statement will not cause a different behavior. It will fail to compile.So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2?If I remember correctly, one of D's design policies is that a D code that looks like C code should behave like C. Are we giving up that policy?
Nov 16 2009
On 11/16/2009 06:16 PM, Denis Koroskin wrote:Yes. I should have written "a valid D code".If I remember correctly, one of D's design policies is that a D code that looks like C code should behave like C. Are we giving up that policy?Correction: either behave like C, or raise a compile-time error.Missing break statement will not cause a different behavior. It will fail to compile.Could you clarify? In you proposal, does a break statement breaks out of the switch? Then, for (;;) { switch (foo) { case "FOO": break; } } In C, 'break' exits the for-loop. In your proposal, it doesn't.
Nov 16 2009
On Mon, 16 Nov 2009 12:48:09 +0300, MIURA Masahiro <echochamber gmail.com> wrote:On 11/16/2009 06:16 PM, Denis Koroskin wrote:Either I don't know C, or it breaks the switch, not the for-loop. In both languages. Before *and* after the proposed change. There was no suggestion to remove breaks and make them implicit. The proposal was to make code flow control statements mandatory (either of break, return or goto).Yes. I should have written "a valid D code".If I remember correctly, one of D's design policies is that a D code that looks like C code should behave like C. Are we giving up that policy?Correction: either behave like C, or raise a compile-time error.Missing break statement will not cause a different behavior. It will fail to compile.Could you clarify? In you proposal, does a break statement breaks out of the switch? Then, for (;;) { switch (foo) { case "FOO": break; } } In C, 'break' exits the for-loop. In your proposal, it doesn't.
Nov 16 2009
On 11/16/2009 06:55 PM, Denis Koroskin wrote:Either I don't know C, or it breaks the switch, not the for-loop. In both languages. Before *and* after the proposed change.Arrrgh, please don't mind. My mistake. I'm sorry.
Nov 16 2009
On Nov 16, 09 17:48, MIURA Masahiro wrote:On 11/16/2009 06:16 PM, Denis Koroskin wrote:switch (x) { case 2: doSomething(); // At this point: // Compiles fine in C. // Falls through to the next (irrelevant) branch. // Compile-time error in D (missing "break;" or "goto case 3;") case 3: doSomeTotallyDifferentThing(x, ~x); break; ... } In you proposal, does a break statementYes. I should have written "a valid D code".If I remember correctly, one of D's design policies is that a D code that looks like C code should behave like C. Are we giving up that policy?Correction: either behave like C, or raise a compile-time error.Missing break statement will not cause a different behavior. It will fail to compile.Could you clarify?breaks out of the switch? Then, for (;;) { switch (foo) { case "FOO": break; } } In C, 'break' exits the for-loop. In your proposal, it doesn't.Check with you compiler. In C the inner "break" doesn't break the for loop.
Nov 16 2009
On 11/16/2009 07:05 PM, KennyTM~ wrote:Check with you compiler. In C the inner "break" doesn't break the for loop.Yes that's right. My mistake.
Nov 16 2009
KennyTM~:switch (x) { case 2: doSomething(); // At this point: // Compiles fine in C. // Falls through to the next (irrelevant) branch. // Compile-time error in D (missing "break;" or "goto case 3;") case 3: doSomeTotallyDifferentThing(x, ~x); break; ... }Nice idea. "goto case 3;" isn't the nicest syntax to step to the following case, but it has the advantage that it keeps working if you shuffle the cases. So this design is acceptable, avoids introducing a third version of switch, keeps the minimal compatibility necessary for C. If other people like it, then it may be implemented in D2. Anyone sees disadvantages? Bye, bearophile
Nov 16 2009
On Mon, 16 Nov 2009 11:58:44 +0300, MIURA Masahiro <echochamber gmail.com> wrote:On 11/16/2009 02:49 AM, Chad J wrote:It is a good policy to follow but there are cases where C behavior may differ from D behavior (when code is copy-pasted and not adjusted according to languages difference). I've just posted an example in a different thread: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=101322So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2?If I remember correctly, one of D's design policies is that a D code that looks like C code should behave like C. Are we giving up that policy?
Nov 16 2009
Don:(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
bearophile wrote:Don:I don't know about "forcing people" to write such but perhaps it could be an "option for people" :-) Actually I quite like the brevity you propose but would it be a challenge for the comma operator? While ago, I got D multi-dimensional array syntax messed up and declared such an animal as int[3,4,5] which effectively ended up declaring the beast as int[5]. Cheers Justin(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
On Mon, 16 Nov 2009 15:48:16 +0300, Justin Johansson <no spam.com> wrote:bearophile wrote:Wow, this definitely needs to be bug-reported!Don:I don't know about "forcing people" to write such but perhaps it could be an "option for people" :-) Actually I quite like the brevity you propose but would it be a challenge for the comma operator? While ago, I got D multi-dimensional array syntax messed up and declared such an animal as int[3,4,5] which effectively ended up declaring the beast as int[5]. Cheers Justin(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
Denis Koroskin wrote:On Mon, 16 Nov 2009 15:48:16 +0300, Justin Johansson <no spam.com> wrote:Wilco. http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=19904bearophile wrote:Wow, this definitely needs to be bug-reported!Don:I don't know about "forcing people" to write such but perhaps it could be an "option for people" :-) Actually I quite like the brevity you propose but would it be a challenge for the comma operator? While ago, I got D multi-dimensional array syntax messed up and declared such an animal as int[3,4,5] which effectively ended up declaring the beast as int[5]. Cheers Justin(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
Justin Johansson wrote:bearophile wrote:The comma operator is another piece of C cruft that needs to go.Don:I don't know about "forcing people" to write such but perhaps it could be an "option for people" :-) Actually I quite like the brevity you propose but would it be a challenge for the comma operator? While ago, I got D multi-dimensional array syntax messed up and declared such an animal as int[3,4,5] which effectively ended up declaring the beast as int[5].(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophileCheers Justin
Nov 16 2009
bearophile wrote:Don:(1) "case A, B, C:" implies a relationship between A, B, and C, which might not exist. They may have nothing in common. (2) it's an extremely common coding style in C, C++. (3) it's more difficult to read.(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
Don:(1) "case A, B, C:" implies a relationship between A, B, and C, which might not exist. They may have nothing in common.It's just a list of things, it's a syntax people adapts too. Here too there's no relationship between x and foo: int x, foo;(2) it's an extremely common coding style in C, C++.If automatic fall-through becomes a syntax error, then allowing it for empty case statements is a special case of a special case. This kind of complexity kills languages. As they say in Python Zen: Special cases aren't special enough to break the rules. And this is D.(3) it's more difficult to read.You can put items in one column anyway, so instead of: case someverylongcase: case anotherverylongcase: case thelastverylongcase: You can write: case someverylongcase, anotherverylongcase, thelastverylongcase: This is not so unreadable. ---------------------- Justin Johansson:Actually I quite like the brevity you propose but would it be a challenge for the comma operator?That's already standard D syntax :-) http://codepad.org/ByvTAs27 Bye, bearophile
Nov 16 2009
bearophile wrote:Don:(1) "case A, B, C:" implies a relationship between A, B, and C, which might not exist. They may have nothing in common.It's just a list of things, it's a syntax people adapts too. Here too there's no relationship between x and foo: int x, foo;(2) it's an extremely common coding style in C, C++.If automatic fall-through becomes a syntax error, then allowing it for empty case statements is a special case of a special case. This kind of complexity kills languages. As they say in Python Zen: Special cases aren't special enough to break the rules. And this is D.(3) it's more difficult to read.You can put items in one column anyway, so instead of: case someverylongcase: case anotherverylongcase: case thelastverylongcase: You can write: case someverylongcase, anotherverylongcase, thelastverylongcase: This is not so unreadable. ---------------------- Justin Johansson:Actually I quite like the brevity you propose but would it be a challenge for the comma operator?That's already standard D syntax :-) http://codepad.org/ByvTAs27 Bye, bearophileThat's already standard D syntax :-)Okay, thanks for reminding me.**What's bad about forcing people to write case A, B, CSo your use of the word "forcing" was quite intentional? Cheers. Must go now to attend to some fall-through cases in my switch statements.** Justin.
Nov 16 2009
On Mon, 16 Nov 2009 14:34:37 +0100, Don wrote:bearophile wrote:(1) case A: case B: case C: implies that there is no relationship between A,B, and C, but which might actually exist. They may have something common. (2) it's an extremely common writing style in human languages, thus aids readability. (3) case A: case B: case C: is ambiguous. It looks like the coder put in place markers for intended code but forgot the code. -- Derek Parnell Melbourne, Australia skype: derek.j.parnellDon:(1) "case A, B, C:" implies a relationship between A, B, and C, which might not exist. They may have nothing in common. (2) it's an extremely common coding style in C, C++. (3) it's more difficult to read.(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
On Mon, 16 Nov 2009 23:36:38 +0300, Derek Parnell <derek psych.ward> wrote:On Mon, 16 Nov 2009 14:34:37 +0100, Don wrote:When porting some C++ code to D (okay, it was DMDFE), I had exact same issue. There is the following macro defined: #define CASE_BASIC_TYPES \ case TOKwchar: case TOKdchar: \ case TOKbit: case TOKbool: case TOKchar: \ case TOKint8: case TOKuns8: \ case TOKint16: case TOKuns16: \ case TOKint32: case TOKuns32: \ case TOKint64: case TOKuns64: \ case TOKfloat32: case TOKfloat64: case TOKfloat80: \ case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \ case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \ case TOKvoid and if was used (and got translated to D) as follows: switch (token) { case TOKidentifier: case TOKenum: case TOKstruct: case TOKimport: CASE_BASIC_TYPES: } Did you noticed it already? It is a valid C code *but* has different semantics! In D, CASE_BASIC_TYPES is merely a label, and it does just nothing. Needless to say the code compiled successfully, but produced weird error messages at run-time. BTW, if a macro was declared as #define BASIC_TYPES \ TOKwchar: case TOKdchar: \ case TOKbit: case TOKbool: case TOKchar: \ case TOKint8: case TOKuns8: \ case TOKint16: case TOKuns16: \ case TOKint32: case TOKuns32: \ case TOKint64: case TOKuns64: \ case TOKfloat32: case TOKfloat64: case TOKfloat80: \ case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \ case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \ case TOKvoid (note an absence of the first case) then it would cause compile-time error instead of run-time bugs. Usage: switch (token) { case TOKidentifier: case TOKenum: case TOKstruct: case TOKimport: case BASIC_TYPES: }bearophile wrote:(1) case A: case B: case C: implies that there is no relationship between A,B, and C, but which might actually exist. They may have something common. (2) it's an extremely common writing style in human languages, thus aids readability. (3) case A: case B: case C: is ambiguous. It looks like the coder put in place markers for intended code but forgot the code.Don:(1) "case A, B, C:" implies a relationship between A, B, and C, which might not exist. They may have nothing in common. (2) it's an extremely common coding style in C, C++. (3) it's more difficult to read.(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 16 2009
Denis Koroskin wrote:BTW, if a macro was declared as #define BASIC_TYPES \ TOKwchar: case TOKdchar: \ case TOKbit: case TOKbool: case TOKchar: \ case TOKint8: case TOKuns8: \ case TOKint16: case TOKuns16: \ case TOKint32: case TOKuns32: \ case TOKint64: case TOKuns64: \ case TOKfloat32: case TOKfloat64: case TOKfloat80: \ case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \ case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \ case TOKvoid (note an absence of the first case) then it would cause compile-time error instead of run-time bugs. Usage: switch (token) { case TOKidentifier: case TOKenum: case TOKstruct: case TOKimport: case BASIC_TYPES: }I like that. Great suggestion!
Nov 16 2009
Derek Parnell wrote:On Mon, 16 Nov 2009 14:34:37 +0100, Don wrote:Yes, of course! In which situation, you use case A, B, C: I'm not arguing AGAINST that syntax, which already exists! Your other two comments aren't worth responding to.bearophile wrote:(1) case A: case B: case C: implies that there is no relationship between A,B, and C, but which might actually exist. They may have something common.Don:(1) "case A, B, C:" implies a relationship between A, B, and C, which might not exist. They may have nothing in common. (2) it's an extremely common coding style in C, C++. (3) it's more difficult to read.(providing that empty fall-through case statements remain valid; disallowing them would be really annoying).What's bad about forcing people to write: case A, B, C: Instead of: case A: case B: case C: ? Bye, bearophile
Nov 17 2009
On Tue, 17 Nov 2009 09:05:48 +0100, Don wrote:Your other two comments aren't worth responding to.I apologize. I also don't know what I said to offend you. I've taken steps to make sure it doesn't happen again. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Nov 17 2009
Andrei Alexandrescu Wrote:Chad J wrote:As long as it's possible to enumerate a list of matches for one case statement then I'm all for it. I very rarely use fall-through in any of my code but lexers/parser, where I enumerate lists of matches everywhere. I'll admit to still being a bit peeved that I have to add default conditions where I only want a break, etc, but I'll concede that the safety is worth what I feel is unnecessary code. Just because "I never hit those bugs in my code" doesn't mean they aren't a common source of problems.So, switch-case statements are a frequent source of nasty bugs. Fixing them (well) requires breaking backwards compatibility. Any chance this will happen for D2? (This is intended as more of a reminder and simple curiosity than a discussion.)I wish very much that a transferring control flow statement (break, return, goto etc.) is required at the end of each case. Then, the rare case when you want to break through is easy to implement as goto case xxx; and all is good. Walter's answer to that has put me to silence for good. "But I use fall-through all the time!" I then knew the feature will never make it.
Nov 16 2009