Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect floating point to integral conversion in NarrowingCompoundAssi…
…gnment Previously it only detected compound assignments to 'deficient' types, which will always require narrowing conversions. But compound assignments from, e.g., double to long also result in implicit narrowing conversions. RELNOTES: Detect floating point to integral conversion in NarrowingCompoundAssignment MOE_MIGRATED_REVID=133902838
- Loading branch information
Showing
3 changed files
with
192 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,49 @@ | |||
The compound assignment `E1 op= E2` could be mistaken for being equivalent to | |||
`E1 = E1 op E2`. However, this is not the case: compound assignment operators | |||
automatically cast the result of the computation to the type on the left hand | |||
side. So E1 op= E2 is actually equivalent to E1 = (T) (E1 op E2), where T is | |||
the type of E1. | |||
|
|||
If the type of the expression is wider than the type of the | |||
variable (i.e. the variable is a byte, char, short, or float), then the | |||
compound assignment will perform a narrowing primitive conversion. Attempting | |||
to perform the equivalent simple assignment would generate a compilation error. | |||
|
|||
For example, the following does not compile: | |||
|
|||
```java | |||
byte b = 0; | |||
b = b << 1; | |||
// ^ | |||
// error: incompatible types: possible lossy conversion from int to byte | |||
``` | |||
|
|||
However, the compound assignment form is allowed: | |||
|
|||
```java | |||
byte b = 0; | |||
b <<= 1; | |||
``` | |||
|
|||
Similarly, if the expression is a floating point type (float or double), | |||
and the variable is an integral type (long, int, short, byte, or char), then | |||
an implicit conversion will be performed. | |||
|
|||
Example: | |||
|
|||
```java | |||
long l = 180; | |||
l = l * 2.0f; | |||
// ^ | |||
// error: incompatible types: possible lossy conversion from float to long | |||
``` | |||
|
|||
Again, the compound assignment form is permitted: | |||
|
|||
```java | |||
long l = 180; | |||
l *= 2.0f; | |||
``` | |||
|
|||
See Puzzle #9 in 'Java Puzzlers: Traps, Pitfalls, and Corner Cases' for more | |||
information. |