if / else led by a negated condition

ID

objectivec.maintainability.inverted_logic

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Control Flow

Language

Objective-C

Description

Reports an if whose condition is a single negation and which has a plain else branch, so the two blocks could be swapped and the ! dropped. A negation combined with && or || is not reported, because removing it there means rewriting the whole condition rather than swapping two blocks. A negated if with no else, a chain ending in else if, and an else with an empty body are not reported either.

Rationale

Reading if (!ready) { … } else { … } costs the reader an extra inversion before they can say which block runs in the ordinary case, and the ordinary case is the one they are usually looking for. The negative branch also comes first, so the exceptional path is what the eye lands on and the main path is the afterthought. In a method with several of these, each one has to be un-negated separately to follow the flow, and the negation is easy to lose when a condition is later extended or extracted.

The following code illustrates the pattern detected by this rule:

@implementation Router
- (void)routeFlag:(BOOL)ready {
    // FLAGGED: if / else led by a negated condition
    if (!ready) {
        [self wait];
    } else {
        [self go];
    }
}

- (void)wait {
}

- (void)go {
}

- (BOOL)isReady {
    return YES;
}
@end

Remediation

Drop the ! and swap the two blocks, so the positive case is stated first and reads directly. Where the negative case is short and leaves the method, an early return is usually better still: keep the guard as if (!ready) { return; } and let the rest of the body run unindented, which removes the else entirely.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved