bugprone-chained-comparison¶
此检查检测可能会导致意外行为或逻辑错误的链式比较运算符。
链式比较是指使用多个比较运算符来比较三个或更多值的表达式。例如,表达式 a < b < c
比较 a
、b
和 c
的值。但是,此表达式不会像 (a < b) && (b < c)
那样进行评估,而这很可能是开发人员的意图。相反,它会像 (a < b) < c
那样进行评估,这可能会产生意外的结果,尤其是在 a
、b
和 c
的类型不同时。
为了避免此类错误,当检测到链式比较运算符时,此检查会发出警告,建议使用括号指定求值顺序,或使用逻辑运算符来分隔比较表达式。
考虑以下示例
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 < b
为 true
,因此表达式 (a < b) < c
会被评估为 1 < c
,这等效于 true < c
,并且在这种情况下无效,因为 b < c
为 false
。
即使上述问题可以检测到 int
与 bool
的比较,但还有一个更危险的示例
bool a = false, b = false, c = true;
if (a == b == c) {
// This block will be executed
}
在此示例中,开发人员想要检查 a
、b
和 c
是否都相等。但是,表达式 a == b == c
会被评估为 (a == b) == c
。由于 a == b
为 true,因此表达式 (a == b) == c
会被评估为 true == c
,这等效于 true == true
。此比较产生 true
,即使 a
和 b
为 false
,并且不等于 c
。
为了避免此问题,开发人员可以使用逻辑运算符来分隔比较表达式,如下所示
if (a == b && b == c) {
// This block will not be executed
}
或者,在比较表达式中使用括号可以使开发人员的意图更加明确,并有助于避免误解。
if ((a == b) == c) {
// This block will be executed
}