Anoying problem, but what else can be done?

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Sat Feb 3 17:01:35 PST 2007


BCS wrote:
> this fails
> 
> foreach(i, j; Tuple!(1,2,3,4)
> {
>  loopLable: while(test())
>  {
>    while(otherTest())
>    {
>      if(lastTest())
>        break loopLabel;
>      else
>        continue  loopLabel;
>    }
>  }
> }
> 
> The reason is that loopLabel is used once for each iteration of the 
> foreach, which is unrolled. Seeing as labels have functions scope, this 
> is an error.
> 
[snip "Duff's Device"-like workaround]
> 
> A better solution would be to define that labels have function scope 
> from a syntactic standpoint, meaning that the first code would be valid 
> because, while the labels references more than one location in the final 
> program, it only occurs onces in the code. This would be somewhat bad 
> but only because you can't jump from one iteration to the next (IIRC the 
> switch/case/goto case can).

I'd like this to work, but for any identifiers (labels, variables, 
aliases, whatever). Whatever is declared in a 'static' foreach body 
should be local to that iteration of it, because AFAICT it's pretty much 
guaranteed to be an error or bug otherwise.

> A better solution would be name:number labels (I'll use the "@" for this 
> but the syntax is irrelevant)
> 
> foreach(i, j; Tuple!(1,2,3,4))
> {
>  loopLable at i: while(test())  // different label each time
>  {
>    while(otherTest())
>    {
>      if(nextTest())
>        break loopLabel at i;      // ok, unique label
>      if(lastText())
>        continue  loopLabel at i;  // ditto
> 
>      static if(i>1) goto loopLabel@(i-1); // math on number ok
>    }
>  }
> }
> 
> It also eliminates the problem of having to do math on case numbers if 
> you have more than one place in the loop you want to jump to.
> 
> foreach(i, j; Tuple!(1,2,3,4))
> {
>  Lable at i:  if(jump()) goto Label at i;
> 
>  Next at i:
>  if(jump()) goto Next at i;
> }
> 
> Anyway, I'm not sure I like any of these, what do you all think of them?

Perhaps your proposed syntax could still be implemented as an additional 
feature allowing you to jump to other iterations, but I think the 
original should just do the "obvious" thing.
Again, if implemented it should also apply to other declarations, not 
just labels.


I ran into a similar situation a few days ago when I declared an alias 
in a 'static' foreach. It kept using the alias from the first iteration 
for all subsequent iterations (IIRC not even a 'duplicate definition' 
error!).



More information about the Digitalmars-d mailing list