digitalmars.D - What is the use case for this weird switch mecanism
- deadalnix (11/11) Oct 30 2012 Today, I noticed by digging into D details the following construct :
- H. S. Teoh (6/20) Oct 30 2012 That's weird. I just did a quick test; apparently statement is never
- Philippe Sigaud (6/10) Oct 30 2012 I've no idea why it's authorized, but it saved my day a week ago, in
- deadalnix (5/16) Oct 30 2012 I usually want to avoid code working in an unexpected way. Even when it
- bearophile (5/7) Oct 30 2012 See also this bug report I've opened time ago:
- Andrej Mitrovic (2/3) Oct 30 2012 There could be a label for a goto there.
- deadalnix (2/5) Oct 30 2012 That still don't explain what the use case is.
- Nick Sabalausky (3/10) Oct 30 2012 Obfuscated coding contests?
- bearophile (4/5) Oct 30 2012 It's there to help programmers create more bugs, of course :o)
- Era Scarecrow (4/7) Oct 30 2012 Maybe variable declaration (as long as they are default(s))? Has
- bearophile (16/19) Oct 30 2012 Declaring variables there is dangerous:
- Era Scarecrow (17/27) Oct 30 2012 Then it's as though it were '= void;' by default. Most curious.
- H. S. Teoh (6/18) Oct 30 2012 Is this the official announcement for the inception of the IODCC? ;-)
- Daniel Murphy (9/13) Oct 30 2012 The structure for switch is:
- Chris Nicholson-Sauls (56/56) Oct 31 2012 Some related actual code from a while back:
- bearophile (4/6) Oct 31 2012 What about writing with(EnumType) switch(val) {...} ?
- Era Scarecrow (13/17) Oct 31 2012 Maybe... But a problem arises when it's function wide, and
- bearophile (4/5) Oct 31 2012 It's not worth the unsafety of the whole switch.
- Era Scarecrow (4/7) Oct 31 2012 What? I'd need a little explanation what you'd mean. besides,
- bearophile (8/12) Nov 05 2012 I meant that semantically clean language features help avoid
- deadalnix (3/55) Nov 05 2012 Wow this is not actually the case presented in y first post, but still
Today, I noticed by digging into D details the following construct : switch(foo) { statement; case A: // Stuffs . . . // Other cases. default: // Stuffs . . . } What the hell statement is supposed to do ? And what is the use case for this ?
Oct 30 2012
On Tue, Oct 30, 2012 at 05:16:48PM +0100, deadalnix wrote:Today, I noticed by digging into D details the following construct : switch(foo) { statement; case A: // Stuffs . . . // Other cases. default: // Stuffs . . . } What the hell statement is supposed to do ? And what is the use case for this ?That's weird. I just did a quick test; apparently statement is never run. I've no idea why it's allowed or what it's for. T -- Debian GNU/Linux: Cray on your desktop.
Oct 30 2012
I've no idea why it's authorized, but it saved my day a week ago, in an automatically-generated switch statement that happened to have a "return true;" inserted at the very beginning. No unit test found that and I saw it only by printing the generated code for another search. In a way, it's logical: the code path jumps to the matching case, so it never sees the first statement block before the first case.What the hell statement is supposed to do ? And what is the use case for this ?That's weird. I just did a quick test; apparently statement is never run. I've no idea why it's allowed or what it's for.
Oct 30 2012
Le 30/10/2012 18:47, Philippe Sigaud a écrit :I usually want to avoid code working in an unexpected way. Even when it make code work when I expect it shouldn't. I wrote about this publicly few mounth ago, and, considering how much return I got, I'm not the only one.I've no idea why it's authorized, but it saved my day a week ago, in an automatically-generated switch statement that happened to have a "return true;" inserted at the very beginning. No unit test found that and I saw it only by printing the generated code for another search. In a way, it's logical: the code path jumps to the matching case, so it never sees the first statement block before the first case.What the hell statement is supposed to do ? And what is the use case for this ?That's weird. I just did a quick test; apparently statement is never run. I've no idea why it's allowed or what it's for.
Oct 30 2012
deadalnix:What the hell statement is supposed to do ? And what is the use case for this ?See also this bug report I've opened time ago: http://d.puremagic.com/issues/show_bug.cgi?id=3820 Bye, bearophile
Oct 30 2012
On 10/30/12, Philippe Sigaud <philippe.sigaud gmail.com> wrote:I've no idea why it's authorizedThere could be a label for a goto there.
Oct 30 2012
Le 30/10/2012 18:57, Andrej Mitrovic a écrit :On 10/30/12, Philippe Sigaud<philippe.sigaud gmail.com> wrote:That still don't explain what the use case is.I've no idea why it's authorizedThere could be a label for a goto there.
Oct 30 2012
On Tue, 30 Oct 2012 21:39:31 +0100 deadalnix <deadalnix gmail.com> wrote:Le 30/10/2012 18:57, Andrej Mitrovic a =E9crit :Obfuscated coding contests?On 10/30/12, Philippe Sigaud<philippe.sigaud gmail.com> wrote:=20 That still don't explain what the use case is.I've no idea why it's authorizedThere could be a label for a goto there.
Oct 30 2012
Nick Sabalausky:Obfuscated coding contests?It's there to help programmers create more bugs, of course :o) Bye, bearophile
Oct 30 2012
On Tuesday, 30 October 2012 at 21:11:57 UTC, bearophile wrote:Nick Sabalausky:Maybe variable declaration (as long as they are default(s))? Has a certain amount of sense, but makes more sense to do it outside the switch case...Obfuscated coding contests?It's there to help programmers create more bugs, of course :o)
Oct 30 2012
Era Scarecrow:Maybe variable declaration (as long as they are default(s))? Has a certain amount of sense, but makes more sense to do it outside the switch case...Declaring variables there is dangerous: import std.stdio; struct Foo { int x = 10; } void main() { int bar; switch(bar) { Foo f; case 10: break; default: writeln(f); // prints garbage } } Bye, bearophile
Oct 30 2012
On Tuesday, 30 October 2012 at 21:40:26 UTC, bearophile wrote:Era Scarecrow:Maybe variable declaration (as long as they are default(s))?Declaring variables there is dangerous:switch(bar) { Foo f; case 10: break; default: writeln(f); // prints garbage }Then it's as though it were '= void;' by default. Most curious. Honestly I'd say it's illegal to have something before any callable case; Besides for goto's it's illegal to jump past declarations, yet this switch case allows it. I'd say one of two things must happen then. 1) Code before the first case is disallowed 2) Code before the first case always runs Option 2 seems silly and unneeded, except it allows a small scope during the switch call, which is it's only possible advantage. The only other advantage is you could have a case disabled and enable it during certain debugging cases, but in those cases why not do the whole block?switch(bar) {static if (DEBUG) { case -10: /*disabled case, or something like that*/ } Foo f;case 10: break;
Oct 30 2012
On Tue, Oct 30, 2012 at 04:51:33PM -0400, Nick Sabalausky wrote:On Tue, 30 Oct 2012 21:39:31 +0100 deadalnix <deadalnix gmail.com> wrote:Is this the official announcement for the inception of the IODCC? ;-) (cf. www.ioccc.org). T -- Those who've learned LaTeX swear by it. Those who are learning LaTeX swear at it. -- Pete BleackleyLe 30/10/2012 18:57, Andrej Mitrovic a écrit :Obfuscated coding contests?On 10/30/12, Philippe Sigaud<philippe.sigaud gmail.com> wrote:That still don't explain what the use case is.I've no idea why it's authorizedThere could be a label for a goto there.
Oct 30 2012
"deadalnix" <deadalnix gmail.com> wrote in message news:k6ouhh$116v$1 digitalmars.com...Today, I noticed by digging into D details the following construct : [snip switch being stupid] What the hell statement is supposed to do ? And what is the use case for this ?The structure for switch is: switch(value) Statement(s) There is very little structure imposed on the statements it contains. If there are any case or default labels inside the switch that are not inside another inner switch, they are linked to the value and can be jumped to. One (the only?) use case for the loose definition is Duff's Device. The reason it's like this in D: that's how it is in C.
Oct 30 2012
Some related actual code from a while back: ParseTree prune ( ParseTree p ) { p.children = p.children.dup; foreach ( ref child ; p.children ) { child = prune( child ); } switch ( p.ruleName ) { // strip prefix/suffix terminals, then if left with only one child, skip over it case "Args" : case "List" : case "Params" : case "Table" : p.children = p.children[ 1 .. $ - 1 ]; if ( p.children.length == 1 ) { // skip over immediate child (always a "Series") case "QualIdent" : case "Type" : p.children = p.children[ 0 ].children; } break; // skip self if it has exactly one child case "Addition" : case "BoolAnd" : case "BoolOr" : case "Comparison" : case "Conditional" : case "MaybeParens" : case "Multiplication" : case "Postfix" : case "Primary" : case "Unary" : if ( p.children.length == 1 ) { // skip self case "Expression" : case "Field" : case "Ident" : case "Literal" : case "PathElem" : case "Statement" : p = p.children[ 0 ]; } break; default: } return p; } Without the loosely defined switch() statement syntax, this would have been a royal pain to piece together. Especially when each block of cases was evolving over time. There is also the trick of doing 'switch(val) with(EnumType) {...}' to bring an enum's members into scope so that cases can be written as 'case Foo:' rather than 'case EnumType.Foo:'. -- Chris Nicholson-Sauls
Oct 31 2012
Chris Nicholson-Sauls:There is also the trick of doing 'switch(val) with(EnumType) {...}'What about writing with(EnumType) switch(val) {...} ? Bye, bearophile
Oct 31 2012
On Wednesday, 31 October 2012 at 22:01:36 UTC, bearophile wrote:Chris Nicholson-Sauls:Maybe... But a problem arises when it's function wide, and should be able to replace (hopefully) any block. Assuming there's no syntactical issues that may break other code. int func() with(EnumType) { //won't compile } int func() { with(EnumType) { //compiles but seems excessive when it doesn't need to... } } But 'switch with' seems the proper way to put it in my mind.There is also the trick of doing 'switch(val) with(EnumType) {...}'What about writing with(EnumType) switch(val) {...} ?
Oct 31 2012
Era Scarecrow:But 'switch with' seems the proper way to put it in my mind.It's not worth the unsafety of the whole switch. Bye, bearophile
Oct 31 2012
On Wednesday, 31 October 2012 at 22:58:32 UTC, bearophile wrote:Era Scarecrow:What? I'd need a little explanation what you'd mean. besides, 'switch with' and 'with switch' are practically identical... aren't they?But 'switch with' seems the proper way to put it in my mind.It's not worth the unsafety of the whole switch.
Oct 31 2012
Era Scarecrow:I meant that semantically clean language features help avoid troubles later while you program :-)It's not worth the unsafety of the whole switch.What? I'd need a little explanation what you'd mean.besides, 'switch with' and 'with switch' are practically identical... aren't they?Yeah, they are practically identical, that's my point. But 'with switch' allows you to to not allow code after the switch, so allows to keep switch syntax cleaner :-) Bye, bearophile
Nov 05 2012
Le 31/10/2012 21:33, Chris Nicholson-Sauls a écrit :Some related actual code from a while back: ParseTree prune ( ParseTree p ) { p.children = p.children.dup; foreach ( ref child ; p.children ) { child = prune( child ); } switch ( p.ruleName ) { // strip prefix/suffix terminals, then if left with only one child, skip over it case "Args" : case "List" : case "Params" : case "Table" : p.children = p.children[ 1 .. $ - 1 ]; if ( p.children.length == 1 ) { // skip over immediate child (always a "Series") case "QualIdent" : case "Type" : p.children = p.children[ 0 ].children; } break; // skip self if it has exactly one child case "Addition" : case "BoolAnd" : case "BoolOr" : case "Comparison" : case "Conditional" : case "MaybeParens" : case "Multiplication" : case "Postfix" : case "Primary" : case "Unary" : if ( p.children.length == 1 ) { // skip self case "Expression" : case "Field" : case "Ident" : case "Literal" : case "PathElem" : case "Statement" : p = p.children[ 0 ]; } break; default: } return p; } Without the loosely defined switch() statement syntax, this would have been a royal pain to piece together. Especially when each block of cases was evolving over time. There is also the trick of doing 'switch(val) with(EnumType) {...}' to bring an enum's members into scope so that cases can be written as 'case Foo:' rather than 'case EnumType.Foo:'. -- Chris Nicholson-SaulsWow this is not actually the case presented in y first post, but still very interesting.
Nov 05 2012