default label is not the last label of the switch

ID

objectivec.correctness.switch_default_not_last

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Control Flow

Language

Objective-C

Description

Reports a switch whose default: label is followed by a further case: label at the same indentation, i.e. the catch-all is written first or in the middle rather than last. A default that closes the switch, a switch that has only a default, and a nested switch whose own labels are indented deeper are not reported.

Rationale

Readers scan a switch expecting the catch-all at the bottom, so a default in the middle hides the arms below it — a value handled by a later case looks unhandled at a glance. It is also a fall-through hazard: unlike a case, a default that is not last must still end in break, and when the arm below is edited the missing jump is easy to miss because the block does not read as the end of the statement.

The following code illustrates the pattern detected by this rule:

@implementation Dispatcher
- (void)defaultFirst:(XYState)state {
    switch (state) {
        // FLAGGED: default label is not the last label of the switch
        default:
            [self unknown];
            break;
        case XYStateIdle:
            [self idle];
            break;
    }
}

- (void)idle { }
- (void)done { }
- (void)run { }
- (void)unknown { }
- (XYState)fallbackFor:(XYState)state { return XYStateIdle; }
@end

Remediation

Move the default: label, with its statements, below the last case: of the switch. If the ordering was deliberate because the arms fall through into one another, make that explicit with a comment on the fall-through, or restructure the arms so each ends in break.

Configuration

This detector does not need any configuration.

References

© 2026 Xygeni. All rights reserved