Assertion condition changes the program state

ID

objectivec.correctness.assert_side_effect

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

low

Resource

Api Misuse

Language

Objective-C

Description

Reports an assertion - NSAssert, NSCAssert, their numbered variants, NSParameterAssert, NSCParameterAssert or C assert - whose condition assigns to something, or increments or decrements it. Comparison operators, a condition that only reads state, a format argument that happens to contain =, and a copy of the shape inside a comment are not reported.

Rationale

Assertion macros expand to nothing once NS_BLOCK_ASSERTIONS or NDEBUG is defined, which is the normal configuration for a release build. Everything the condition does therefore disappears with it: the cursor is not advanced, the field is not assigned, the counter is not decremented. The program then behaves one way under test and another way in the hands of users, and the difference is invisible in the source because the statement is still there. An assignment written where == was meant makes it worse still - the assertion passes whenever the assigned value is non-zero, so the check it was supposed to perform never happens in either build.

The following code illustrates the pattern detected by this rule:

@implementation Buffer
- (void)appendByte:(uint8_t)byte {
    // FLAGGED: Assertion condition changes the program state
    NSAssert(self.cursor++ < self.capacity, @"buffer overrun");
    self.bytes[self.cursor] = byte;
}

- (void)notifyReady { }
@end

Remediation

Move the work out of the assertion and assert on the result - self.cursor += 1; followed by NSAssert(self.cursor < self.capacity, @"buffer overrun");. If the condition was meant to be a comparison, restore the == that was typed as =. Keep assertion conditions to pure reads, so that removing every assertion from the build cannot change what the program does.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved