xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/bugprone/inc-dec-in-conditions.rst (revision f27f22b34516dcb744077710c19d475367e3ef03)
1.. title:: clang-tidy - bugprone-inc-dec-in-conditions
2
3bugprone-inc-dec-in-conditions
4==============================
5
6Detects when a variable is both incremented/decremented and referenced inside a
7complex condition and suggests moving them outside to avoid ambiguity in the
8variable's value.
9
10When a variable is modified and also used in a complex condition, it can lead to
11unexpected behavior. The side-effect of changing the variable's value within the
12condition can make the code difficult to reason about. Additionally, the
13developer's intended timing for the modification of the variable may not be
14clear, leading to misunderstandings and errors. This can be particularly
15problematic when the condition involves logical operators like ``&&`` and
16``||``, where the order of evaluation can further complicate the situation.
17
18Consider the following example:
19
20.. code-block:: c++
21
22  int i = 0;
23  // ...
24  if (i++ < 5 && i > 0) {
25    // do something
26  }
27
28In this example, the result of the expression may not be what the developer
29intended. The original intention of the developer could be to increment ``i``
30after the entire condition is evaluated, but in reality, i will be incremented
31before ``i > 0`` is executed. This can lead to unexpected behavior and bugs in
32the code. To fix this issue, the developer should separate the increment
33operation from the condition and perform it separately. For example, they can
34increment ``i`` in a separate statement before or after the condition is
35evaluated. This ensures that the value of ``i`` is predictable and consistent
36throughout the code.
37
38.. code-block:: c++
39
40  int i = 0;
41  // ...
42  i++;
43  if (i <= 5 && i > 0) {
44    // do something
45  }
46
47Another common issue occurs when multiple increments or decrements are performed
48on the same variable inside a complex condition. For example:
49
50.. code-block:: c++
51
52  int i = 4;
53  // ...
54  if (i++ < 5 || --i > 2) {
55    // do something
56  }
57
58There is a potential issue with this code due to the order of evaluation in C++.
59The ``||`` operator used in the condition statement guarantees that if the first
60operand evaluates to ``true``, the second operand will not be evaluated. This
61means that if ``i`` were initially ``4``, the first operand ``i < 5`` would
62evaluate to ``true`` and the second operand ``i > 2`` would not be evaluated.
63As a result, the decrement operation ``--i`` would not be executed and ``i``
64would hold value ``5``, which may not be the intended behavior for the developer.
65
66To avoid this potential issue, the both increment and decrement operation on
67``i`` should be moved outside the condition statement.
68