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.