On Tue, Jan 09, 2018 at 03:26:32PM -0500, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 1/9/18 2:31 PM, H. S. Teoh wrote:
[...]
> > If there were a hypothetical `static continue` or `static break`
> > that's recognized by the static foreach unroller, we could in theory
> > automate this branching in the compiler itself, e.g., by deleting
> > the AST nodes that would be skipped.  Of course, the syntax need not
> > be `static continue`; if there were a way to overload `break LABEL;`
> > for the same purpose, i.e., have the static foreach unroller inspect
> > the label to see if it is referring to the static foreach itself,
> > then this would work.
> > 
> > But I don't know the static foreach implementation enough to be able
> > to tell whether this is actually possible at the time static foreach
> > is processed, or whether there may be some chicken-and-egg problem
> > with inspecting the target of a break/continue before semantic or
> > whatever.
> 
> Yeah, I think in terms of static foreach, it's not a straightforward
> problem. Because the compiler may not know enough information at the
> time to figure out whether it should still keep generating code.
> 
> For example:
> 
> static foreach(i; 0 .. 5)
> {
>    if(i == 3) static break;
>    static assert(i < 3);
> }
> 
> How does it know whether the static break should be "executed" at
> compile-time if it hasn't evaluated the if-statement? The code would
> have to have no runtime branches to make sure that static break can be
> evaluated at compile-time.
[...]

Static foreach does not (and should not!) evaluate a runtime branch,
because this is before CTFE even happens. CTFE cannot happen until the
static foreach has been fully unrolled, so it doesn't even make sense to
talk about evaluating the if-statement at this point. For your example
to make sense, you'd have to use static if, then the break would be
possible, and non-problematic.

Of course, that still doesn't solve the problem of what static break is
supposed to do from inside a runtime branch. I'm tempted to say that
static break should mean "delete all subsequent nodes from the AST that
follows this node in depth-first traversal order", so your example above
would be transformed into:

        if (0 == 3) {}
        // all subsequent iterations deleted

because the static break is unconditionally compiled (it has nothing to
do with the runtime branch).  You'd have to use static if to make it
conditionally-compiled and thus not instantly aborting the loop.

Such semantics would be logically consistent, but unfortunately rather
counterintuitive at first glance.


T

-- 
If the comments and the code disagree, it's likely that *both* are wrong. -- 
Christopher

Reply via email to