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