...
Left- and right-shift operators are often employed to multiply or divide a number by a power of 2. This compromises code readability and portability for the sake of often-illusory speed gains. The JVM will usually make such optimizations automatically; further, and, unlike a programmer, the JVM can optimize for the implementation details of the current platform. This noncompliant code example includes both bit manipulation and arithmetic manipulation manipulations of the integer x
that conceptually contains a numeric value. The result is a prematurely optimized statement that assigns 5x + 1
to x
.
...
Code Block | ||
---|---|---|
| ||
int x = 50; x = 5 * x + 1; |
A reviewer may could now recognize that the operation should also be checked for overflow. This might not have been apparent in the original, noncompliant code example. For more information, see guideline "INT00-J. Ensure that integer operations do not result in overflow."
Noncompliant Code Example (Logical Right Shift)
...
Code Block | ||
---|---|---|
| ||
int x = -50; x >>= 2; |
After execution of this code sequence is run, x
contains the value -13
rather than the expected -12
. Arithmetic right shift truncates its results towards negative infinity; integer division truncates towards zero.
...
In this noncompliant code example, a programmer is attempting to fetch four values from a byte array and pack them into the the integer variable result
. The integer value in this example represents a bit collection and , not a numeric value.
Code Block | ||
---|---|---|
| ||
// b[] is a byte array, initialized to 0xff byte[] b = new byte[] {-1, -1, -1, -1}; int result = 0; for (int i = 0; i < 4; i++) { result = ((result << 8) + b[i]); } |
Wiki Markup |
---|
In performing the bitwise operation, the value of the byte array element {{b\[i\]}} is promoted to an {{int}} by sign-extension. When a byte array element contains a negative value (for example, {{0xff}}), the sign-extension propagates 1-bits into the upper 24 bits of the {{int}}. This behavior maycould be unexpected if the programmer is assuming that {{byte}} is an unsigned type. In this example, adding the promoted byte values to {{result}} fails to result in a packed integer representation of the bytes \[[FindBugs 2008|AA. Bibliography#FindBugs 08]\]. |
...
Code Block | ||
---|---|---|
| ||
byte[] b = new byte[] {-1, -1, -1, -1}; int result = 0; for (int i = 0; i < 4; i++) { result = ((result << 8) | (b[i] & 0xff)); } |
Exceptions
NUM02-EX0EX1: Bitwise operations may be used to construct constant expressions. Nevertheless, as a matter of style, we recommend replacing such constant expressions with the equivalent hexadecimal constants ; 0x1FFFF, in this case.
Code Block | ||
---|---|---|
| ||
int limit = 1 << 17 - 1; // 2^17 - 1 = 131071 |
NUM02-EX1EX2: Data that is normally treated arithmetically may be treated with bitwise operations for the purpose of serialization or deserialization. This is often required for reading or writing the data from a file or network socket. Bitwise operations are also permitted when reading or writing the data from a tightly packed data structure of bytes.
...
Performing bit manipulation and arithmetic operations on the same variable obscures the programmer's intentions and reduces readability. This, in turn, makes it more difficult for a security auditor or maintainer to determine which checks must be performed to eliminate security flaws and ensure data integrity.
...
CERT C Secure Coding Standard: "INT14-C. Avoid performing bitwise and arithmetic operations on the same data"
CERT C++ Secure Coding Standard: "INT14-CPP. Avoid performing bitwise and arithmetic operations on the same data"
Bibliography
Wiki Markup |
---|
\[[Steele 1977|AA. Bibliography#Steele 1977]\] |
...