Thread overview
Compile time foreach with switch
Apr 21, 2017
Johan Fjeldtvedt
Apr 21, 2017
Adam D. Ruppe
Apr 21, 2017
H. S. Teoh
Apr 21, 2017
Johan Fjeldtvedt
Apr 22, 2017
Nick Treleaven
Apr 24, 2017
Nick Treleaven
April 21, 2017
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?
April 21, 2017
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.)

April 21, 2017
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
April 21, 2017
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.
April 22, 2017
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.
April 24, 2017
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