Note | ||
---|---|---|
| ||
This rule may be deprecated and replaced by a similar guideline. 06/28/2014 -- Version 1.0 |
JAccording According to the JLS, §15.7, "Evaluation Order" [JLS 2005]:
...
The programmer in this example incorrectly assumes that the rightmost subexpression is evaluated first because the *
operator has a higher precedence than the +
operator and because the subexpression is parenthesized. This assumption leads to the incorrect conclusion that number
is assigned 0 because of the rightmost number = get()
subexpression. Consequently, the test in the left-hand subexpression is expected to reject the unprivileged user because the value of number
is below the threshold of 10
.
...
Code Block | ||
---|---|---|
| ||
class BadPrecedence { public static void main(String[] args) { int number = 17; int threshold = 10; number = (number > threshold ? 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; } } |
...
This noncompliant code example reorders the previous expression so that the left-to-right evaluation order of the operands corresponds with the programmer's intent. Although this code performs as expected, it still represents poor practice by writing to number
three times in a single expression.
...
Code Block | ||
---|---|---|
| ||
final int authnum = get(); number = ((31 * (number + 1)) * authnum) + (authnum > threshold ? 0 : -2); |
Exceptions
EXP05-EX0: The increment and decrement operators (++)
and (--)
read a numeric variable, and then assign a new value to the variable. While Although these operators read and modify a value, they are well-understood and are an exception to this rule. This exception does not apply if a value modified by an increment or decrement operator is subsequently read or written.
EXP05-EX1: The conditional-or ||
and conditional-and &&
operators have well-understood semantics. Writes Writes followed by subsequent writes or reads do not violate this rule if they occur in different operands of ||
or &&
. Consider Consider the following code example:
...
This rule is not violated by the controlling expression of the while
loop because the rule is not violated by any operand to the conditional-and &&
operators. The subexpressions (i = in.read()) != -1
have one assignment and one side effect (the reading of a character from in
).
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP05-J | lowLow | unlikelyUnlikely | mediumMedium | P2 | L3 |
Automated Detection
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.
...
...