Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The relational and equality operators are left-associative in C. Consequently, C, unlike many other languages, allows chaining of relational and equality operators. Subclause 6.5.8, footnote 107, of the C Standard [ISO/IEC 9899:2011], says:

The expression a<b<c is not interpreted as in ordinary mathematics. As the syntax indicates, it means (a<b)<c; in other words, "if a is less than b, compare 1 to c; otherwise, compare 0 to c."

These operators are left-associative, which means the leftmost comparison is performed first, and the result is compared with the rightmost comparison. This syntax not non-associative as they often are in other languages. A comparison such as{{x<=y<=z}}, for example, is equivalent to (x<=y ? 1 : 0) <= z, which is a different interpretation from that of ordinary mathematical notation. This allows a programmer to write an expression (particularly an expression used as a condition) that can be easily misinterpreted.

Noncompliant Code Example

While Although this noncompliant code example compiles correctly, it is unlikely that it means what the author of the code intended. :

Code Block
bgColor#FFcccc
langc

int a = 2;
int b = 2;
int c = 2;
//* ... */
if ( a < b < c ) //* condition #1, misleading, Misleading; likely bug */
//* ... */
if ( a == b == c ) // condition #2, misleading,* Misleading; likely bug */

Condition #1 The expression a < b < c evaluates to true , rather than false , as its author probably intended, and condition #2 to false, and the expression a == b == c evaluates to false , rather than true , as its author probably intended, to true.

Compliant Solution

Treat relational and equality operators as if it were invalid to chain them.:

Code Block
bgColor#ccccff
langc

if ( (a < b) && (b < c) ) //* clearer,Clearer and probably what was intended */
//* ... */
if ( (a == b) && (a == c) ) /* Ditto */ ditto

Risk Assessment

Incorrect use of relational and equality operators can lead to incorrect control flow.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP13-C

Low

Unlikely

Medium

P2

L3

Automated Detection

...

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
chained-comparisonFully checked

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

CC2.EXP13

Fully implemented

GCC
Include Page
GCC_V
GCC_V


Option -Wparentheses warns if a comparison like

...

x<=y<=z

...

appears

...

; this warning is also enabled by -Wall

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C3392, C3401, C4111, C4112, C4113


LDRA tool suite
Include Page
LDRA_V
LDRA_V
433 SFully implemented
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

503, 731

Fully supported

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. EXP13-CChecks for possibly unintended evaluation of expression because of operator precedence rules (rec.

...

fully covered)


PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V709
RuleChecker
Include Page
RuleChecker_V
RuleChecker_V
chained-comparisonFully checked

Related Guidelines

Other Languages

...

...

Bibliography

[ISO/IEC 9899:2011]Subclause 6.5.8, "Relational Operators"


...

Image Added Image Added Image Added

Risk Assessment

Incorrect use of relational and equality operators can lead to incorrect control flow.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP09-A

1 (low)

1 (unlikely)

2 (medium)

P2

L3

Image Removed      03. Expressions (EXP)      EXP30-C. Do not depend on order of evaluation between sequence points