bugprone-chained-comparison¶
Check detects chained comparison operators that can lead to unintended behavior or logical errors.
Chained comparisons are expressions that use multiple comparison operators
to compare three or more values. For example, the expression a < b < c
compares the values of a
, b
, and c
. However, this expression does
not evaluate as (a < b) && (b < c)
, which is probably what the developer
intended. Instead, it evaluates as (a < b) < c
, which may produce
unintended results, especially when the types of a
, b
, and c
are
different.
To avoid such errors, the check will issue a warning when a chained comparison operator is detected, suggesting to use parentheses to specify the order of evaluation or to use a logical operator to separate comparison expressions.
Consider the following examples:
int a = 2, b = 6, c = 4;
if (a < b < c) {
// This block will be executed
}
In this example, the developer intended to check if a
is less than b
and b
is less than c
. However, the expression a < b < c
is
equivalent to (a < b) < c
. Since a < b
is true
, the expression
(a < b) < c
is evaluated as 1 < c
, which is equivalent to true < c
and is invalid in this case as b < c
is false
.
Even that above issue could be detected as comparison of int
to bool
,
there is more dangerous example:
bool a = false, b = false, c = true;
if (a == b == c) {
// This block will be executed
}
In this example, the developer intended to check if a
, b
, and c
are
all equal. However, the expression a == b == c
is evaluated as
(a == b) == c
. Since a == b
is true, the expression (a == b) == c
is evaluated as true == c
, which is equivalent to true == true
.
This comparison yields true
, even though a
and b
are false
, and
are not equal to c
.
To avoid this issue, the developer can use a logical operator to separate the comparison expressions, like this:
if (a == b && b == c) {
// This block will not be executed
}
Alternatively, use of parentheses in the comparison expressions can make the developer’s intention more explicit and help avoid misunderstanding.
if ((a == b) == c) {
// This block will be executed
}