The logical AND and logical OR operators (&&
, and ||
, respectively) exhibit "short-circuit" operation. That is, the second operand is not evaluated if the result can be deduced solely by evaluating the first operand. Consequently,
Programmers should exercise caution if the second operand should not contain contains side effects because , if it does, it is not apparent if the side effect occurs.
Non-Compliant Code Example
it may not be apparent whether the side effects actually occur.
In the following code, the value of i
is incremented only when i >= 0
:
Code Block | ||
---|---|---|
enum { max = 15 };
int i = /* Initialize to user-supplied value */ | ||
Code Block | ||
| ||
int i; int max; if ( (i >= 0) && ( (i++) <= max) ) { /* codeCode */ } |
Although the behavior is well defined, it is not immediately obvious whether or not i
gets incremented.
Noncompliant Code Example
In this noncompliant code example, the second operand of the logical OR operator invokes a function that results in side effects:
Code Block | ||||
---|---|---|---|---|
| ||||
char *p = /* Initialize; may or may not be NULL */
if (p || (p = (char *) malloc(BUF_SIZE)) ) {
/* Perform some computation based on p */
free(p);
p = NULL;
} else {
/* Handle malloc() error */
return;
}
|
Because malloc()
is called only if p
is NULL
when entering the if
clause, free()
might be called with a pointer to local data not allocated by malloc()
. (See MEM34-C. Only free memory allocated dynamically.) This behavior is partially due to the uncertainty of whether or not malloc()
is actually calledIt is unclear whether the value of i
will be incremented as a result of evaluating the condition.
Compliant Solution
In this compliant solution, the behavior is much clearer, a second pointer, q
, is used to indicate whether malloc()
is called; if not, q
remains set to NULL
. Passing NULL
to free()
is guaranteed to safely do nothing.
Code Block | ||
---|---|---|
| ||
int i;
int max;
if ( (i >= 0 && (i + 1) <= max) ) {
i++;
/* code */
}
|
Risk Assessment
| |||
char *p = /* Initialize; may or may not be NULL */
char *q = NULL;
if (p == NULL) {
q = (char *) malloc(BUF_SIZE);
p = q;
}
if (p == NULL) {
/* Handle malloc() error */
return;
}
/* Perform some computation based on p */
free(q);
q = NULL;
|
Risk Assessment
Failing to understand the short-circuit behavior of Attempting to modify an object that is the second operand to the logical OR or AND operator may cause that object to take on an unexpected value. This can lead to unintended program behavior.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP02-C | Low | Unlikely | Medium | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| logop-side-effect | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-EXP02 |
1 (low)
1 (unlikely)
3 (low)
P3
L3
Fully implemented | |||||||||
Compass/ROSE | Could detect possible violations of this recommendation by reporting expressions with side effects, including function calls, that appear on the right-hand side of an | ||||||||
Helix QAC |
| C3415 | |||||||
Klocwork |
| MISRA.LOGIC.SIDEEFF | |||||||
LDRA tool suite |
| 35 D | Fully implemented | ||||||
Parasoft C/C++test |
| CERT_C-EXP02-a | The right-hand operand of a logical && or || operator shall not contain side effects | ||||||
PC-lint Plus |
| 9007 | Fully supported | ||||||
RuleChecker |
| logop-side-effect | Fully checked | ||||||
SonarQube C/C++ Plugin |
| SideEffectInRightHandSideOfLogical |
Related Vulnerabilities
Search for Examples of vulnerabilities resulting from the violation of this recommendation can be found rule on the CERT website.
References
Related Guidelines
SEI CERT C++ Coding Standard | VOID EXP02-CPP. Be aware of the short-circuit behavior of the logical AND and OR operators |
MITRE CWE | CWE-768, Incorrect short circuit evaluation |
...
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.5.13, "Logical AND operator," and Section 6.5.14, "Logical OR operator" Wiki Markup