Just want to sync and make sure we're on the same page here...

Certain constructs (switch expression, switch statement, for/while/do) give meaning to some flavor of break.  Inside those, you can't use the other flavor, nor can you break "through" a construct of the opposite flavor.

    switch-expression {
        break / break-label not allowed;
        break-expr allowed;
        continue, return not allowed;

        if (foo) {
            break / break-label disallowed;
            break-expr allowed;
        }

        LOOP:
        for (...) {
            break, continue allowed;
            return not allowed;
            break-label allowed if within the switch expression
            break expression not allowed;
        }

        switch (e) {
            // same as for loop
            switch-expression {
                break expr allowed
                break, break-label, continue, return not allowed
        }
    }

More formally; we can construct a table whose rows are the control constructs and whose columns are the nonlocal branches, and whose entries are "handlers" for a nonlocal branch.  Each block has a parent (the immediately enclosing block.)

            break-e   break   break-l   continue   return

switch-e      L         X       X         X          X
switch-s      X         L       P         L          P
for           X         L       P         L          P
while         X         L       P         L          P
block         P         P       P         P          P
labeled       X         X L*        X          P
lambda        X         X       X         X L
method        X         X X         X          L

The handlers mean:

X -- not allowed
P -- let the parent handle it
L -- handle it and complete normally
L* -- handle it and complete normally if the labels match, otherwise P

(I might have mangled the labeled row, in which case surely Guy will correct me.)  The idea here is that each nested block acts as an "exception handler", catching some exceptions, and propagating others, and some contexts act as exception barriers, like trying to throw a "continue" out of a method.


On 3/2/2018 9:30 AM, Remi Forax wrote:
Hi all,
as far as i remember, the current idea to differentiate between a break label 
and a break value is to let the compiler figure this out,
i wonder if it's not simpler to disallow break label (and continue label) 
inside an expression switch.

After all, an expression switch do not exist yet, so no backward compatibility 
issue, it may make some refactoring impossible but had the great advantage to 
do not allow a lot of puzzler codes like the one below.

enum Result {
   ONE, MANY
}

Result result(String[] args) {
   ONE: for(String s: args) {
      return switch(s) {
        case "several":
        case "many":
          break MANY;
        case "one":
          break ONE;
        default:
          continue;
      };
   }
   throw ...;
}

Rémi

Reply via email to