CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
82 lines
2.6 KiB
ReStructuredText
82 lines
2.6 KiB
ReStructuredText
.. title:: clang-tidy - bugprone-chained-comparison
|
|
|
|
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:
|
|
|
|
.. code-block:: c++
|
|
|
|
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:
|
|
|
|
.. code-block:: c++
|
|
|
|
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:
|
|
|
|
.. code-block:: c++
|
|
|
|
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.
|
|
|
|
.. code-block:: c++
|
|
|
|
if ((a == b) == c) {
|
|
// This block will be executed
|
|
}
|
|
|
|
Options
|
|
-------
|
|
|
|
.. option:: IgnoreMacros
|
|
|
|
If `true`, the check will not warn on chained comparisons inside macros.
|
|
Default is `false`.
|
|
|