bugprone-chained-comparison

此检查检测可能会导致意外行为或逻辑错误的链式比较运算符。

链式比较是指使用多个比较运算符来比较三个或更多值的表达式。例如,表达式 a < b < c 比较 abc 的值。但是,此表达式不会像 (a < b) && (b < c) 那样进行评估,而这很可能是开发人员的意图。相反,它会像 (a < b) < c 那样进行评估,这可能会产生意外的结果,尤其是在 abc 的类型不同时。

为了避免此类错误,当检测到链式比较运算符时,此检查会发出警告,建议使用括号指定求值顺序,或使用逻辑运算符来分隔比较表达式。

考虑以下示例

int a = 2, b = 6, c = 4;
if (a < b < c) {
    // This block will be executed
}

在此示例中,开发人员想要检查 a 是否小于 b,并且 b 是否小于 c。但是,表达式 a < b < c 等效于 (a < b) < c。由于 a < btrue,因此表达式 (a < b) < c 会被评估为 1 < c,这等效于 true < c,并且在这种情况下无效,因为 b < cfalse

即使上述问题可以检测到 intbool 的比较,但还有一个更危险的示例

bool a = false, b = false, c = true;
if (a == b == c) {
    // This block will be executed
}

在此示例中,开发人员想要检查 abc 是否都相等。但是,表达式 a == b == c 会被评估为 (a == b) == c。由于 a == b 为 true,因此表达式 (a == b) == c 会被评估为 true == c,这等效于 true == true。此比较产生 true,即使 abfalse,并且不等于 c

为了避免此问题,开发人员可以使用逻辑运算符来分隔比较表达式,如下所示

if (a == b && b == c) {
    // This block will not be executed
}

或者,在比较表达式中使用括号可以使开发人员的意图更加明确,并有助于避免误解。

if ((a == b) == c) {
    // This block will be executed
}