bugprone-inc-dec-in-conditions

Detects when a variable is both incremented/decremented and referenced inside a complex condition and suggests moving them outside to avoid ambiguity in the variable’s value.

When a variable is modified and also used in a complex condition, it can lead to unexpected behavior. The side-effect of changing the variable’s value within the condition can make the code difficult to reason about. Additionally, the developer’s intended timing for the modification of the variable may not be clear, leading to misunderstandings and errors. This can be particularly problematic when the condition involves logical operators like && and ||, where the order of evaluation can further complicate the situation.

Consider the following example:

int i = 0;
// ...
if (i++ < 5 && i > 0) {
  // do something
}

In this example, the result of the expression may not be what the developer intended. The original intention of the developer could be to increment i after the entire condition is evaluated, but in reality, i will be incremented before i > 0 is executed. This can lead to unexpected behavior and bugs in the code. To fix this issue, the developer should separate the increment operation from the condition and perform it separately. For example, they can increment i in a separate statement before or after the condition is evaluated. This ensures that the value of i is predictable and consistent throughout the code.

int i = 0;
// ...
i++;
if (i <= 5 && i > 0) {
  // do something
}

Another common issue occurs when multiple increments or decrements are performed on the same variable inside a complex condition. For example:

int i = 4;
// ...
if (i++ < 5 || --i > 2) {
  // do something
}

There is a potential issue with this code due to the order of evaluation in C++. The || operator used in the condition statement guarantees that if the first operand evaluates to true, the second operand will not be evaluated. This means that if i were initially 4, the first operand i < 5 would evaluate to true and the second operand i > 2 would not be evaluated. As a result, the decrement operation --i would not be executed and i would hold value 5, which may not be the intended behavior for the developer.

To avoid this potential issue, the both increment and decrement operation on i should be moved outside the condition statement.