digitalmars.D.learn - Inside the switch statement
- Sam Hu (35/35) Jun 08 2009 To save time ,just get to my point:I do not understand why such code bel...
- BCS (5/45) Jun 08 2009 This is a classic C thing. The short explanation is that a switch is a c...
- Ellery Newcomer (3/20) Jun 08 2009 I would guess from the D specs
- Sam Hu (5/6) Jun 08 2009 It is from the spec:
- grauzone (3/5) Jun 09 2009 of C is that switches don't break automatically before each case label.
- BCS (3/12) Jun 09 2009 I'm sorry, you don't have my sympathy on this one. There are to many pla...
- grauzone (14/28) Jun 09 2009 What kind of fall-throughs were these?
- BCS (7/39) Jun 09 2009 I don't do that, I go with this form:
- Ary Borenszweig (17/50) Jun 09 2009 The solution is to forbid fallthrough, and change the switch syntax:
- Saaa (2/35) Jun 09 2009 Doesn't support B :)
- Ary Borenszweig (4/47) Jun 09 2009 The idea is that it not supporting B is something good.
- Saaa (6/14) Jun 09 2009 I know this is your idea, but as BCS doesn't support this idea.
- Ary Borenszweig (3/20) Jun 09 2009 A warning *is* nothing. :-P
- Saaa (2/3) Jun 09 2009 Your idea was to give an error on the case (B) he uses. Or did I miss
- Ary Borenszweig (3/7) Jun 09 2009 You missed the alternative syntax to get the same behaviour. But it's a
- Saaa (2/4) Jun 09 2009 Do you mean the multiple cases?
- Ary Borenszweig (3/8) Jun 09 2009 Yes, but make the "multiple cases" the *only* way to make case
- Saaa (1/3) Jun 09 2009 That is the same as giving an error on case B, right?
- Saaa (1/1) Jun 09 2009 I mean, the syntax stays the same.
- Ary Borenszweig (4/8) Jun 09 2009 Well, yes, but you also have to prepare your mind for the change. This
- Saaa (1/3) Jun 09 2009 ;)
- Saaa (3/3) Jun 09 2009 (nah, just kidding, you're right, I didn't realize it :-P)
- Ary Borenszweig (2/6) Jun 09 2009 Write a lexer and a parser.
- Saaa (1/2) Jun 09 2009 how do you mean?
- BCS (9/19) Jun 09 2009 that /does not/ support the use case I have used:
- Steve Schveighoffer (14/56) Jun 10 2009 case value1:
- Derek Parnell (53/67) Jun 09 2009 It is not an either-or situation.
- BCS (5/37) Jun 09 2009 C# sort of takes this approach (by using goto case EXP;) but doesn't hav...
- Kagamin (12/45) Jun 11 2009 The Duff's device is said to be an optimization, but I get blunt device ...
- bearophile (4/5) Jun 11 2009 Compilers already know about the Duff's device, and sometimes they use i...
- Joel C. Salomon (6/7) Jun 15 2009 Read Duff’s post: “this loop was the bottleneck in a real-time anima...
To save time ,just get to my point:I do not understand why such code below inside the switch ... case statement is allowed ,what is the point of do ... while...: This example uses a mixin to implement a generic Duff's device for an arbitrary statement (in this case, the arbitrary statement is in bold). A nested function is generated as well as a delegate literal, these can be inlined by the compiler: template duffs_device(alias id1, alias id2, alias s) { void duff_loop() { if (id1 < id2) { typeof(id1) n = (id2 - id1 + 7) / 8; switch ((id2 - id1) % 8) { case 0: do { s(); case 7: s(); case 6: s(); case 5: s(); case 4: s(); case 3: s(); case 2: s(); case 1: s(); } while (--n > 0); } } } } void foo() { writefln("foo"); } void test() { int i = 1; int j = 11; mixin duffs_device!(i, j, delegate { foo(); } ); duff_loop(); // executes foo() 10 times } Thanks in advance. Regards, Sam
Jun 08 2009
Hello Sam,To save time ,just get to my point:I do not understand why such code below inside the switch ... case statement is allowed ,what is the point of do ... while...:This is a classic C thing. The short explanation is that a switch is a conditional, many way goto and the labels can be *anywhere* in the body (except inside another switch). For the more in depth version Google "duff's device".This example uses a mixin to implement a generic Duff's device for an arbitrary statement (in this case, the arbitrary statement is in bold).BTW: where is this from?A nested function is generated as well as a delegate literal, these can be inlined by the compiler: template duffs_device(alias id1, alias id2, alias s) { void duff_loop() { if (id1 < id2) { typeof(id1) n = (id2 - id1 + 7) / 8; switch ((id2 - id1) % 8) { case 0: do { s(); case 7: s(); case 6: s(); case 5: s(); case 4: s(); case 3: s(); case 2: s(); case 1: s(); } while (--n > 0); } } } } void foo() { writefln("foo"); } void test() { int i = 1; int j = 11; mixin duffs_device!(i, j, delegate { foo(); } ); duff_loop(); // executes foo() 10 times }
Jun 08 2009
BCS wrote:Hello Sam,I would guess from the D specs http://www.digitalmars.com/d/1.0/template-mixin.htmlTo save time ,just get to my point:I do not understand why such code below inside the switch ... case statement is allowed ,what is the point of do ... while...:This is a classic C thing. The short explanation is that a switch is a conditional, many way goto and the labels can be *anywhere* in the body (except inside another switch). For the more in depth version Google "duff's device".This example uses a mixin to implement a generic Duff's device for an arbitrary statement (in this case, the arbitrary statement is in bold).BTW: where is this from?
Jun 08 2009
Thanks so much for all your help!I am studying hard to *loop unrolling*.BTW: where is this from?It is from the spec: http://www.digitalmars.com/d/1.0/template-mixin.html BTW,is this Duff? http://groups.google.com/group/net.lang.c/msg/66008138e07aa94c
Jun 08 2009
http://groups.google.com/group/net.lang.c/msg/66008138e07aa94cMany people (even Brian Kernighan?) have said that the worst featureof C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D.
Jun 09 2009
Hello grauzone,I'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out.http://groups.google.com/group/net.lang.c/msg/66008138e07aa94cMany people (even Brian Kernighan?) have said that the worst feature of C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D.
Jun 09 2009
BCS wrote:Hello grauzone,What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break;I'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out.http://groups.google.com/group/net.lang.c/msg/66008138e07aa94cMany people (even Brian Kernighan?) have said that the worst feature of C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D.
Jun 09 2009
Hello grauzone,BCS wrote:I don't do that, I go with this form: case value1, value2, valueN: code1(); break; case B, The most usefull case was where I used the switch as a "jump into the middle of this block of code" device.Hello grauzone,What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break;I'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out.http://groups.google.com/group/net.lang.c/msg/66008138e07aa94cMany people (even Brian Kernighan?) have said that the worst feature of C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D.B: case value1: code1(); case value2: code2(); break;
Jun 09 2009
grauzone wrote:BCS wrote:The solution is to forbid fallthrough, and change the switch syntax: switch(value) { case 1: case 2: // something break; } gives: Error, missing break at the end of case1. But: switch(value) { case 1, 2: // something break; } works as expected. What's wrong with that?Hello grauzone,What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break;I'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out.http://groups.google.com/group/net.lang.c/msg/66008138e07aa94cMany people (even Brian Kernighan?) have said that the worst feature of C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D.
Jun 09 2009
Doesn't support B :) How about a warning instead?What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break;The solution is to forbid fallthrough, and change the switch syntax: switch(value) { case 1: case 2: // something break; } gives: Error, missing break at the end of case1. But: switch(value) { case 1, 2: // something break; } works as expected. What's wrong with that?
Jun 09 2009
Saaa wrote:The idea is that it not supporting B is something good. An error is ok, and if you want to translate C code then it's really easy to change the code to not give errors.Doesn't support B :) How about a warning instead?What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break;The solution is to forbid fallthrough, and change the switch syntax: switch(value) { case 1: case 2: // something break; } gives: Error, missing break at the end of case1. But: switch(value) { case 1, 2: // something break; } works as expected. What's wrong with that?
Jun 09 2009
I know this is your idea, but as BCS doesn't support this idea. You should have replied to him iso grauzone. I personally never had any problems with falling through. The IDE ( descent :) indents it nicely.The idea is that it not supporting B is something good.What's wrong with that?Doesn't support B :) How about a warning instead?An error is ok, and if you want to translate C code then it's really easy to change the code to not give errors.I don't think you will get that, thus maybe a warning is better than nothing?
Jun 09 2009
Saaa wrote:How do you know? BCS didn't reply to my idea.I know this is your idea, but as BCS doesn't support this idea.The idea is that it not supporting B is something good.What's wrong with that?Doesn't support B :) How about a warning instead?You should have replied to him iso grauzone. I personally never had any problems with falling through. The IDE ( descent :) indents it nicely.A warning *is* nothing. :-PAn error is ok, and if you want to translate C code then it's really easy to change the code to not give errors.I don't think you will get that, thus maybe a warning is better than nothing?
Jun 09 2009
How do you know? BCS didn't reply to my idea.Your idea was to give an error on the case (B) he uses. Or did I miss something?
Jun 09 2009
Saaa wrote:You missed the alternative syntax to get the same behaviour. But it's a very subtle difference.How do you know? BCS didn't reply to my idea.Your idea was to give an error on the case (B) he uses. Or did I miss something?
Jun 09 2009
You missed the alternative syntax to get the same behaviour. But it's a very subtle difference.Do you mean the multiple cases? http://www.digitalmars.com/d/1.0/statement.html#SwitchStatement
Jun 09 2009
Saaa wrote:Yes, but make the "multiple cases" the *only* way to make case statements fallthrough. That would be the change.You missed the alternative syntax to get the same behaviour. But it's a very subtle difference.Do you mean the multiple cases? http://www.digitalmars.com/d/1.0/statement.html#SwitchStatement
Jun 09 2009
Yes, but make the "multiple cases" the *only* way to make case statements fallthrough. That would be the change.That is the same as giving an error on case B, right?
Jun 09 2009
Saaa wrote:Well, yes, but you also have to prepare your mind for the change. This is a huge step. (nah, just kidding, you're right, I didn't realize it :-P)Yes, but make the "multiple cases" the *only* way to make case statements fallthrough. That would be the change.That is the same as giving an error on case B, right?
Jun 09 2009
Well, yes, but you also have to prepare your mind for the change. This is a huge step.;)
Jun 09 2009
(nah, just kidding, you're right, I didn't realize it :-P) Ok, enough kidding around, lets get back to you helping me with 'code generalization' :P
Jun 09 2009
Saaa wrote:(nah, just kidding, you're right, I didn't realize it :-P) Ok, enough kidding around, lets get back to you helping me with 'code generalization' :PWrite a lexer and a parser.
Jun 09 2009
Hello Ary,Saaa wrote:that /does not/ support the use case I have used: switch(n) { case 1: some_func(); case 2: some_other_func(); }Yes, but make the "multiple cases" the *only* way to make case statements fallthrough. That would be the change.You missed the alternative syntax to get the same behaviour. But it's a very subtle difference.Do you mean the multiple cases? http://www.digitalmars.com/d/1.0/statement.html#SwitchStatement
Jun 09 2009
On Tue, 09 Jun 2009 19:35:51 +0200, Saaa wrote:case value1: code1(); goto case value2; // already valid D code // or goto case; // already valid D code case value2: code2(); break; Should be uncommon enough that the extra clarification is warranted IMO. I believe I've fallen victim to accidental fall-throughs more than I've found uses for them... vote++ -SteveDoesn't support B :)What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break;The solution is to forbid fallthrough, and change the switch syntax: switch(value) { case 1: case 2: // something break; } gives: Error, missing break at the end of case1. But: switch(value) { case 1, 2: // something break; } works as expected. What's wrong with that?
Jun 10 2009
On Tue, 9 Jun 2009 16:28:58 +0000 (UTC), BCS wrote:Hello grauzone,It is not an either-or situation. We achieved both models in the up-coming version of Euphoria, at the minor cost of a new keyword. By default, it does not do fallthru. Each case is its own master and the physical placement inside the switch is not relevant. switch EXPR do case VAL1 then STATEMENTS... case VAL2 then STATEMENTS... case VAL3 then STATEMENTS... end switch But, if for some good reason you need to do fallthru ... switch EXPR with fallthru do case VAL1 then STATEMENTS... case VAL2 then STATEMENTS... case VAL3 then STATEMENTS... end switch It that situation, the absence of a 'break' means that program flow falls through to the next case. You can still insert 'break' at any point to skip to the end of the switch statement, even in the default format. However, additionally in the default format you can use 'fallthru' to let flow drop to the next case.... switch EXPR do case VAL1 then STATEMENTS... case VAL2 then STATEMENTS... fallthru -->>> This makes flow fall through. case VAL3 then STATEMENTS... end switch So, if one considers improving D's switch, it is possible to have both models if one is not frightened of new keywords. For example ... select (EXPR) { case VAL1: STATEMENTS... case VAL2: STATEMENTS... case VAL3: STATEMENTS... } would only execute ONE of the selected cases. -- Derek Parnell Melbourne, Australia skype: derek.j.parnellI'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out.http://groups.google.com/group/net.lang.c/msg/66008138e07aa94cMany people (even Brian Kernighan?) have said that the worst feature of C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D.
Jun 09 2009
Hello Derek,On Tue, 9 Jun 2009 16:28:58 +0000 (UTC), BCS wrote:[...]I'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out.However, additionally in the default format you can use 'fallthru' to let flow drop to the next case.... switch EXPR do case VAL1 then STATEMENTS... case VAL2 then STATEMENTS... fallthru -->>> This makes flow fall through. case VAL3 then STATEMENTS... end switch So, if one considers improving D's switch, it is possible to have both models if one is not frightened of new keywords. For example ... select (EXPR) { case VAL1: STATEMENTS... case VAL2: STATEMENTS... case VAL3: STATEMENTS... } would only execute ONE of the selected cases.any generic "goto next" ability and I would find that very painful in some template code.
Jun 09 2009
template duffs_device(alias id1, alias id2, alias s) { void duff_loop() { if (id1 < id2) { typeof(id1) n = (id2 - id1 + 7) / 8; switch ((id2 - id1) % 8) { case 0: do { s(); case 7: s(); case 6: s(); case 5: s(); case 4: s(); case 3: s(); case 2: s(); case 1: s(); } while (--n > 0); } } } } void foo() { writefln("foo"); } void test() { int i = 1; int j = 11; mixin duffs_device!(i, j, delegate { foo(); } ); duff_loop(); // executes foo() 10 times }The Duff's device is said to be an optimization, but I get blunt device only 0.7% slower. template blunt_device(alias id1, alias id2, alias s) { void blunt_loop() { if (id1 < id2) { typeof(id1) i = id2 - id1; while(i-->0)s(); } } }
Jun 11 2009
Kagamin:The Duff's device is said to be an optimization, but I get blunt device only 0.7% slower.Compilers already know about the Duff's device, and sometimes they use it automatically. Bye, bearophile
Jun 11 2009
Kagamin wrote:The Duff's device is said to be an optimization, but I get blunt device only 0.7% slower.Read Duff’s post: “this loop was the bottleneck in a real-time animation playback program”, and all the Device is doing is unwinding the loop a few times. Optimization comes because — on the particular system the code was written for — the eight-times-unwound loop fit nicely into cache. —Joel Salomon
Jun 15 2009