Boolean expression with five or more operands

ID

objectivec.maintainability.expression_too_complex

Severity

info

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Complexity

Language

Objective-C

Description

Reports a boolean expression that chains five or more operands with the same logical operator - four or more &&, or four or more ||, between the start of the statement and its terminating ; or {. The expression may be written over several lines. Operators inside a string literal do not count, and neither do operators in a comment.

Rationale

A reader has to hold every operand and the whole truth table in mind at once to work out when a long boolean chain is true, and to decide which operand a fix or a new requirement belongs to. The number of combinations a test suite needs in order to exercise the condition grows with each operand, so the long chains are exactly the conditions that end up partly untested. A chain that long is usually testing several independent things at once, each of which deserves a name.

The following code illustrates the pattern detected by this rule:

@implementation Gate

- (BOOL)allowUser:(NSString *)name a:(BOOL)a b:(BOOL)b c:(BOOL)c d:(BOOL)d e:(BOOL)e {
    // FLAGGED: Boolean expression with five or more operands
    if (a && b && c && d && e) {
        return YES;
    }

    // FLAGGED: Boolean expression with five or more operands
    if (a ||
        b ||
        c ||
        d ||
        e) {
        return YES;
    }

    // FLAGGED: Boolean expression with five or more operands
    BOOL allowed = a && b && c && d && e;

    // FLAGGED: Boolean expression with five or more operands
    if ([name isEqualToString:@"root"] && a && b && c && d) {
        return NO;
    }

    if (a && b && c && d) {
        return YES;
    }

    if ((a && b) || (c && d)) {
        return YES;
    }

    // Two separate statements, two operators each.
    BOOL first = a && b;
    BOOL second = c && d;

    // if (a && b && c && d && e) {
    NSLog(@"if (a && b && c && d && e) {");
    /* if (a && b && c && d && e) { */

    return allowed && first && second;
}

@end

Remediation

Extract a coherent group of the operands into a local BOOL with a name that states what it means, or into a small predicate method on the receiver - BOOL hasValidSession = a && b && c; followed by if (hasValidSession && d && e). Where the operands guard genuinely unrelated concerns, split the condition into separate statements so each can fail on its own terms.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved