...
However, the program grants access to the unauthorized user because evaluation of the side-effect-infested subexpressions follows the left-to-right ordering rule.
Code Block | ||
---|---|---|
| ||
class BadPrecedence {
public static void main(String[] args) {
int number = 17;
int[] threshold = new int[20];
threshold[0] = 10;
number = (number > threshold[0]? 0 : -2)
+ ((31 * ++number) * (number = get()));
// ...
if (number == 0) {
System.out.println("Access granted");
} else {
System.out.println("Denied access"); // number = -2
}
}
public static int get() {
int number = 0;
// Assign number to non zero value if authorized else 0
return number;
}
}
|
...
Although this code performs as expected, it still represents poor practice by writing to number
three times in a single expression.
Code Block | ||
---|---|---|
| ||
int number = 17;
number = ((31 * ++number) * (number=get())) + (number > threshold[0]? 0 : -2);
|
...
This compliant solution uses equivalent code with no side effects and performs not more than one write per expression. The resulting expression can be reordered without concern for the evaluation order of the component expressions, making the code easier to understand and maintain.
Code Block | ||
---|---|---|
| ||
int number = 17;
final int authnum = get();
number = ((31 * (number + 1)) * authnum) + (authnum > threshold[0]? 0 : -2);
|
...
EXP05-EX1: The logical operators ||
and &&
have well-understood short-circuit semantics, so expressions involving these operators do not violate this rule. Consider the following code:
Code Block | ||
---|---|---|
| ||
public void exampleMethod(InputStream in) {
int i;
// Skip one char, process next
while ((i = in.read()) != -1 && (i = in.read()) != -1) {
// ...
}
}
|
...
Detection of all expressions involving both side effects and multiple operator precedence levels is straightforward. Determining the correctness of such uses is infeasible in the general case; heuristic warnings could be useful.
Tool | Version | Checker | Description |
---|---|---|---|
SonarQube Plugin | 2.4 | S881 |
Related Guidelines
EXP30-C. Do not depend on the order of evaluation for side effects | |
EXP30-CPP. Do not depend on order of evaluation between sequence points | |
Side Effects and Order of Evaluation [SAM] |
...
02. Expressions (EXP) EXP06-J. Do not use side-effecting expressions in assertions