bugprone-inc-dec-in-conditions

检测在复杂条件中同时对变量进行自增/自减和引用,并建议将它们移出条件以避免变量值歧义。

当在复杂条件中同时修改变量并使用其值时,可能会导致意想不到的行为。在条件内部改变变量值的副作用会使代码难以理解。此外,开发人员修改变量的预期时机可能不明确,导致误解和错误。当条件涉及逻辑运算符(如 &&||)时,这个问题尤其严重,因为运算符的求值顺序会进一步加剧情况。

请考虑以下示例

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

在这个示例中,表达式的结果可能与开发人员的意图不符。开发人员最初的意图可能是先计算整个条件,然后再将 i 自增,但实际上,i 会先自增,然后再执行 i > 0。这会导致代码出现意想不到的行为和错误。要解决这个问题,开发人员应该将自增操作与条件分离,分别执行。例如,他们可以在计算条件之前或之后使用单独的语句来自增 i。这样可以确保 i 的值在整个代码中可预测且一致。

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

另一个常见问题是在复杂条件中对同一个变量进行多次自增或自减操作。例如

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

这段代码存在潜在问题,因为 C++ 中的求值顺序问题。条件语句中使用的 || 运算符保证如果第一个操作数的值为 true,则不会计算第二个操作数。这意味着如果 i 最初为 4,则第一个操作数 i < 5 的值为 true,并且不会计算第二个操作数 i > 2。因此,自减操作 --i 不会执行,i 的值为 5,这可能不是开发人员的预期行为。

为了避免此潜在问题,应该将对 i 的自增和自减操作都移出条件语句。