Labeled control
A loop may carry a label. Labeled break(label); and continue(label); then
target that loop specifically, which is how you escape or restart an outer
loop from inside an inner one.
Naming a loop
Prefix any loop form with label::
func:failsafe = int32(tbb32:err) {
exit 1;
};
func:main = int32() {
int32:hits = 0i32;
outer: loop(0i32, 3i32, 1i32) {
inner: loop(0i32, 3i32, 1i32) {
if ($ == 1i32) { continue(outer); }
hits += 1i32;
}
}
exit hits;
};
break(label)
break(label); leaves the named loop and every loop nested inside it, resuming
after the named loop:
search: loop(0i32, 10i32, 1i32) {
loop(0i32, 10i32, 1i32) {
if (found()) { break(search); } // exits both loops
}
}
continue(label)
continue(label); jumps to the back-edge of the named loop, abandoning any
inner loops' remaining work for that pass:
rows: loop(0i32, h, 1i32) {
loop(0i32, w, 1i32) {
if (skip_row()) { continue(rows); } // next row, skip rest of cols
}
}
Bare vs labeled
- Bare
break;/continue;always act on the innermost loop. - Labeled
break(L);/continue(L);act on the loop namedL, which may be any enclosing loop including the innermost.
Use a label only when you actually need to steer an outer loop; bare forms keep the common case uncluttered.
Next: Nested loops.