Increment or decrement inside a sizeof operand never executes

ID

objectivec.correctness.side_effect_in_sizeof

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Dead Code

Language

Objective-C

Description

Reports an increment or decrement appearing inside the parentheses of a sizeof operand - sizeof(i)`, `sizeof(i), sizeof(values[i])`, `sizeof(*p). An increment elsewhere in the same expression, such as sizeof(values) + i`, is not reported, and neither are occurrences inside a comment or a string literal. An operand that wraps the increment in a further pair of parentheses - `sizeof(*(p)) - is beyond what a lexical scan can bound and is not reported.

Rationale

sizeof is resolved from the operand’s type, and outside the variable-length-array case the operand is never evaluated. The increment therefore does not happen: the counter the surrounding code relies on is never advanced, so a loop that walks a buffer with sizeof(*cursor++) stays on the first element forever. Nothing in the source marks the difference between the increment that runs and the one that does not, and the compiler usually issues no diagnostic, so the loop simply behaves as if the statement were missing.

The following code illustrates the pattern detected by this rule:

@implementation Buffers
- (void)withSideEffects {
    NSInteger index = 0;
    NSInteger values[8] = {0};
    NSInteger *cursor = values;
    // FLAGGED: Increment or decrement inside a sizeof operand never executes
    size_t postIncrement = sizeof(index++);
    // FLAGGED: Increment or decrement inside a sizeof operand never executes
    size_t preIncrement = sizeof(++index);
    // FLAGGED: Increment or decrement inside a sizeof operand never executes
    size_t postDecrement = sizeof(index--);
    // FLAGGED: Increment or decrement inside a sizeof operand never executes
    size_t subscripted = sizeof(values[index++]);
    // FLAGGED: Increment or decrement inside a sizeof operand never executes
    size_t dereferenced = sizeof(*cursor++);
    NSLog(@"%zu %zu %zu %zu %zu %ld", postIncrement, preIncrement, postDecrement,
          subscripted, dereferenced, (long)index);
}
@end

Remediation

Move the increment out of the sizeof expression and give it its own statement, before or after the one that uses the size. Where the size of the pointed-to element is what is wanted, sizeof(*cursor) states it without touching the cursor, and the advance can then be written where it is meant to happen.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved