Loop body ends with an unconditional break or continue

ID

objectivec.correctness.branching_last_in_loop

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

low

Resource

Control Flow

Language

Objective-C

Description

Reports a for or while whose body is a flat run of statements ending in an unconditional break; or continue;. A jump guarded by an if, one written inside a nested block, and a break belonging to an inner switch are not reported, and neither is a loop written inside a comment.

Rationale

An unconditional break at the bottom of the body means the loop runs exactly once, so the header promises iteration the code never performs — a reader budgets for a loop and a maintainer adds a second element to the collection expecting it to be handled. An unconditional continue there is the mirror image: it jumps to the point control was already going to reach. Both are usually what remains after the condition that guarded the jump was deleted or moved.

The following code illustrates the pattern detected by this rule:

@implementation Scanner
- (void)takeTheFirstItem:(NSArray *)items {
    // FLAGGED: Loop body ends with an unconditional break or continue
    for (id item in items) {
        [self process:item];
        break;
    }
}

- (BOOL)busy { return NO; }
- (BOOL)matches:(id)item { return NO; }
- (NSInteger)kindOf:(id)item { return 0; }
- (void)process:(id)item { }
- (void)tick { }
@end

Remediation

For a break, drop the loop and operate on the single element the code actually wants — firstObject, or an index — or restore the condition the jump was meant to carry. For a continue, delete it.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved