digitalmars.D.bugs - [Issue 7835] New: Ignored break inside static foreach
- d-bugmail puremagic.com (59/59) Apr 05 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (14/67) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (15/15) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (8/12) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (35/35) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (30/30) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (11/43) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (17/49) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (16/28) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (14/14) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
- d-bugmail puremagic.com (7/11) Apr 06 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7835
http://d.puremagic.com/issues/show_bug.cgi?id=7835 Summary: Ignored break inside static foreach Product: D Version: D2 Platform: x86 OS/Version: Windows Status: NEW Keywords: wrong-code Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc --- Comment #0 from bearophile_hugs eml.cc 2012-04-05 17:40:12 PDT --- This D2 program compiles with no warnings or errors with DMD 2.059beta: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; } default: printf("default"); } } But it runs in a wrong way, as you see: ...>dmd -run test.d 2 b default ...>dmd -w -run test.d test.d(12): Error: switch case fallthrough - use 'goto default;' if intended So the break inside the static foreach is ignored. (This idiom of using a static foreach inside a switch is handy to generate switch cases.) Note: adding a second break, like this, doesn't improve the situation: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; break; } default: printf("default"); } } test.d(10): Warning: statement is not reachable test.d(10): Warning: statement is not reachable test.d(12): Error: switch case fallthrough - use 'goto default;' if intended -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 05 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 Dmitry Olshansky <dmitry.olsh gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dmitry.olsh gmail.com --- Comment #1 from Dmitry Olshansky <dmitry.olsh gmail.com> 2012-04-06 07:15:55 PDT --- (In reply to comment #0)This D2 program compiles with no warnings or errors with DMD 2.059beta: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b';L_MySwitch:switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break L_MySwitch; } default: printf("default"); } }For these cases I recommend to use labeled breaks so that it's more clear for humans and compiler alike.But it runs in a wrong way, as you see: ...>dmd -run test.d 2 b default ...>dmd -w -run test.d test.d(12): Error: switch case fallthrough - use 'goto default;' if intended So the break inside the static foreach is ignored. (This idiom of using a static foreach inside a switch is handy to generate switch cases.) Note: adding a second break, like this, doesn't improve the situation: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; break; } default: printf("default"); } }It can't help because the second break is by definition unreachable. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 timon.gehr gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |timon.gehr gmx.ch Resolution| |INVALID --- Comment #2 from timon.gehr gmx.ch 2012-04-06 07:38:55 PDT --- Not a bug. break applies to the innermost statement that can be broken out from. This includes foreach. (I use this idiom often. Use labeled break to break from the switch.) Please reopen as enhancement if you think the code should be illegal. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 --- Comment #3 from bearophile_hugs eml.cc 2012-04-06 10:06:56 PDT --- (In reply to comment #2)Not a bug. break applies to the innermost statement that can be broken out from. This includes foreach. (I use this idiom often. Use labeled break to break from the switch.)You are right, thank you. (My error was to think that "static foreach" doesn't support break.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords|wrong-code |diagnostic Status|RESOLVED |REOPENED Resolution|INVALID | Summary|Ignored break inside static |switch case fallthrough |foreach |error despite a break | |inside static foreach --- Comment #4 from bearophile_hugs eml.cc 2012-04-06 10:18:05 PDT --- Reopened, because you have missed the error message in my bug report. Using a labeled break: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; MySwitch: switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break MySwitch; } default: printf("default"); } } DMD 2.059 beta gives (compiling with -w): test.d(12): Error: switch case fallthrough - use 'goto default;' if intended I have also changed the issue title to better reflect the problem, now the Keywords is 'diagnostic' because it's giving a warning where there is nothing to warn against. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 --- Comment #5 from bearophile_hugs eml.cc 2012-04-06 11:32:39 PDT --- This compiles with no warnings and it seems to work correctly, but I don't fully understand it: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; MySwitch: switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; } break; default: printf("default"); } } Is it correct? if the break inside here is meant to be the foreach break: { case o: printf("2 %c\n", c); break; } Then why a single break is enough after: foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; } break; despite the foreach synthesizes more than one switch case? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 --- Comment #6 from Dmitry Olshansky <dmitry.olsh gmail.com> 2012-04-06 11:37:01 PDT --- (In reply to comment #5)This compiles with no warnings and it seems to work correctly, but I don't fully understand it: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; MySwitch: switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; } break; default: printf("default"); } } Is it correct? if the break inside here is meant to be the foreach break:Yes.{ case o: printf("2 %c\n", c); break; }No it's {case 0: printf("2 %c\n", c); } the break did his job already, it can't work twice.Then why a single break is enough after: foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; }Then the code below gives you one break after that statement.break; despite the foreach synthesizes more than one switch case?foreach synthesizes exactly one statement here. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 --- Comment #7 from timon.gehr gmx.ch 2012-04-06 11:41:49 PDT --- (In reply to comment #5)This compiles with no warnings and it seems to work correctly, but I don't fully understand it: import core.stdc.stdio: printf; template TypeTuple(TList...) { alias TList TypeTuple; } void main() { char c = 'b'; MySwitch: switch (c) { case 'a': printf("1 a\n"); break; foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; } break; default: printf("default"); } } Is it correct? if the break inside here is meant to be the foreach break: { case o: printf("2 %c\n", c); break; } Then why a single break is enough after: foreach (o; TypeTuple!('b', 'c')) { case o: printf("2 %c\n", c); break; } break; despite the foreach synthesizes more than one switch case?Your code is expanded to: void main() { char c = 'b'; switch (c) { case 'a': printf("1 a\n"); break; {case 'b': printf("2 %c\n", c); goto break_foreach;} {case 'c': printf("2 %c\n", c); goto break_foreach;} break_foreach: break; default: printf("default"); } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED Resolution| |INVALID --- Comment #8 from bearophile_hugs eml.cc 2012-04-06 13:12:01 PDT --- (In reply to comment #7)Your code is expanded to: void main() { char c = 'b'; switch (c) { case 'a': printf("1 a\n"); break; {case 'b': printf("2 %c\n", c); goto break_foreach;} {case 'c': printf("2 %c\n", c); goto break_foreach;} break_foreach: break; default: printf("default"); } }Thank you again Timon :-) So there is no bug here. This was not easy to understand for me. (Maybe D newbies will enjoy to read an example of this in some D tips&trickls somewhere, or maybe it was just a conceptualization problem of mine.) Issue closed again, as invalid. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 Brad Roberts <braddr puremagic.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED CC| |braddr puremagic.com Resolution|INVALID | --- Comment #9 from Brad Roberts <braddr puremagic.com> 2012-04-06 15:11:51 PDT --- I think that the expansion of the static foreach is wrong. It explains the behavior, but doesn't excuse it. I think the bug report is valid. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7835 --- Comment #10 from timon.gehr gmx.ch 2012-04-06 15:21:47 PDT --- (In reply to comment #9)I think that the expansion of the static foreach is wrong. It explains the behavior, but doesn't excuse it. I think the bug report is valid.What would be your expected behavior? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2012