www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compile time foreach with switch

reply Johan Fjeldtvedt <jaffe1 gmail.com> writes:
I was a bit surprised to find out 
(https://forum.dlang.org/post/csiwyetjkttlxxnwndif forum.dlang.org) that
compile time foreach-loops can be used inside switch-statements. I tried the
following:

import std.stdio;
import std.typecons;

void foo(string s) {
     enum es = tuple("a", "b", "c");
     switch (s) {
       foreach (e; es) {
         case e:
             writeln("matched ", e);
             break;
       }
     default:
         writeln("no match");
         break;
     }
}

void main() {
     foo("a");
}

However, this prints both "matched a" and "no match". It seems 
like either the break or the default: label is ignored. In this 
example I could have used return of course, but is this behavior 
correct?
Apr 21
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 21 April 2017 at 19:09:25 UTC, Johan Fjeldtvedt wrote:
 void foo(string s) {
     enum es = tuple("a", "b", "c");
     switch (s) {
       foreach (e; es) {
         case e:
             writeln("matched ", e);
             break;
       }
Let me remove some surrounding stuff and ask you what happens: foreach (e; es) { if(s == c) { writeln("matched ", e); break; } } What does that break do? Then realize that it does exactly the same thing when it is inside a switch... it always breaks the innermost thing, which happens to be this loop. (note that cases are not `breaked`, the switch is.)
Apr 21
next sibling parent Johan Fjeldtvedt <jaffe1 gmail.com> writes:
On Friday, 21 April 2017 at 19:17:32 UTC, Adam D. Ruppe wrote:
 On Friday, 21 April 2017 at 19:09:25 UTC, Johan Fjeldtvedt 
 wrote:
 void foo(string s) {
     enum es = tuple("a", "b", "c");
     switch (s) {
       foreach (e; es) {
         case e:
             writeln("matched ", e);
             break;
       }
Let me remove some surrounding stuff and ask you what happens: foreach (e; es) { if(s == c) { writeln("matched ", e); break; } } What does that break do? Then realize that it does exactly the same thing when it is inside a switch... it always breaks the innermost thing, which happens to be this loop. (note that cases are not `breaked`, the switch is.)
*facepalm* Of course! Thanks.
Apr 21
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Apr 21, 2017 at 07:17:32PM +0000, Adam D. Ruppe via Digitalmars-d-learn
wrote:
 On Friday, 21 April 2017 at 19:09:25 UTC, Johan Fjeldtvedt wrote:
 void foo(string s) {
     enum es = tuple("a", "b", "c");
     switch (s) {
       foreach (e; es) {
         case e:
             writeln("matched ", e);
             break;
       }
Let me remove some surrounding stuff and ask you what happens: foreach (e; es) { if(s == c) { writeln("matched ", e); break; } } What does that break do? Then realize that it does exactly the same thing when it is inside a switch... it always breaks the innermost thing, which happens to be this loop. (note that cases are not `breaked`, the switch is.)
Yeah, you want to label your switch statement, say `mySwitch:`, so that you can do a `break mySwitch;` T -- Knowledge is that area of ignorance that we arrange and classify. -- Ambrose Bierce
Apr 21
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Friday, 21 April 2017 at 19:17:32 UTC, Adam D. Ruppe wrote:
 Then realize that it does exactly the same thing when it is 
 inside a switch... it always breaks the innermost thing, which 
 happens to be this loop. (note that cases are not `breaked`, 
 the switch is.)
By coincidence I ran into this issue recently and assumed that break should break the switch too (and I hadn't read the boost::hana thread). Thanks for explaining, I thought it was probably a compiler bug and hadn't gotten round to investigating further. So the compiler generates something like this: int s = 0; switch (s) { case 0: writeln("matched "); default: writeln("no match"); break; } If I compile the above I get: Deprecation: switch case fallthrough - use 'goto default;' if intended IMO the compiler should issue this warning with the OP's code.
Apr 22
parent Nick Treleaven <nick geany.org> writes:
On Saturday, 22 April 2017 at 11:56:31 UTC, Nick Treleaven wrote:
 If I compile the above I get:
 Deprecation: switch case fallthrough - use 'goto default;' if 
 intended

 IMO the compiler should issue this warning with the OP's code.
https://issues.dlang.org/show_bug.cgi?id=7390#c4
Apr 24