C programmers commonly make errors regarding the precedence rules of C operators due to because of the nonintuitively unintuitive low-precedence levels of "&
", "|
", "^
", "<<
", and ">>
". Mistakes regarding precedence rules can be avoided by the suitable use of parentheses. Using parentheses defensively reduces errors and, if not taken to excess, makes the code more readable.
...
.
Subclause 6.5 of the C Standard defines the precedence of operation by the order of the subclauses.
Noncompliant Code Example
The following C expression, intended intent of the expression in this noncompliant code example is to test the least significant bit of x
:
Code Block | ||||
---|---|---|---|---|
| ||||
x & 1 == 0
|
Because of operator precedence rules, the expression is parsed as
Code Block | ||||
---|---|---|---|---|
| ||||
x & (1 == 0)
|
which the compiler would probably evaluate at compile time evaluates to
Code Block | ||||
---|---|---|---|---|
| ||||
(x & 0)
|
and then to 0
.
Compliant Solution
Adding parentheses to indicate precedence will cause the expression to evaluate as expected.In this compliant solution, parentheses are used to ensure the expression evaluates as expected:
Code Block | ||||
---|---|---|---|---|
| ||||
(x & 1) == 0
|
Exceptions
EXP00-C-EX1: Mathematical expressions that follow algebraic order do not require parentheses. For instance, in the expression
Code Block |
---|
x + y * z
|
the multiplication is performed before the addition by mathematical convention. Consequently, parentheses to enforce the algebraic order would be redundant:
Code Block | ||||
---|---|---|---|---|
| ||||
x + (y * z)
|
Risk Assessment
...
Mistakes regarding precedence rules may cause an expression to be evaluated in an unintended way, which can lead to unexpected and abnormal program behavior.
Recommendation |
---|
Severity | Likelihood | Remediation Cost | Priority | Level | |
---|---|---|---|---|---|
EXP00- |
1 (low)
2 (probable)
2 (medium)
P4
L3
References
...
C | Low | Probable | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC-EXP00 | Fully implemented | ||||||
CodeSonar |
| LANG.STRUCT.PARENS | Missing Parentheses | ||||||
| CC2.EXP00 | Fully implemented | |||||||
Helix QAC |
| C3389, C3390, C3391, C3392, C3393, C3394, C3395, C3396, C3397, C3398, C3399, C3400 | |||||||
Klocwork |
| CERT.EXPR.PARENS | |||||||
LDRA tool suite |
| 361 S, 49 S | Fully implemented | ||||||
Parasoft C/C++test |
| CERT_C-EXP00-a | Use parenthesis to clarify expression order if operators with precedence lower than arithmetic are used | ||||||
PC-lint Plus |
| 9050 | Fully supported | ||||||
Polyspace Bug Finder |
| Checks for possible unintended evaluation of expression because of operator precedence rules (rec. fully covered) | |||||||
PVS-Studio |
| V502, V593, V634, V648, V1104 | |||||||
SonarQube C/C++ Plugin |
| S864 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard | VOID EXP00-CPP. Use parentheses for precedence of operation |
ISO/IEC TR 24772:2013 | Operator Precedence/Order of Evaluation [JCW] |
MISRA C:2012 | Rule 12.1 (advisory) |
Bibliography
...
[Dowd 2006] | Chapter 6, "C Language Issues" ("Precedence," pp. 287–288) |
[Kernighan 1988] |
...
] | Section 6.4.3, |
...
"C Language" |
...
Language" \[[Dowd 06|AA. C References#Dowd 06]\] Chapter 6, "C Language Issues" (Precedence, pp. 287-288)