Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Compiler Bug - Incorrect results are returned in the end (by using for example nested xor-assignment operators)
- ----------------------------------------
- Overview and description:
- ------------------------------
- As this code
- int a = 10, b = 20;
- a ^= (b ^= (a ^= b));
- should swap the values of "a" and "b", actually makes the compiler spit out wrong bytecode,
- hence you get different results in the end.
- Results:
- a = 0
- b = 10
- Where this method
- int a = 10, b = 20;
- a ^= b;
- b ^= a;
- a ^= b;
- returns the correct values.
- Results:
- a = 20
- b = 10
- ----------------------------------------
- Versions:
- ------------------------------
- javac.exe version:
- javac 1.8.0_20
- --------------------
- java.exe version:
- java version "1.8.0_20"
- Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
- Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
- --------------------
- javap.exe version:
- 1.8.0_20
- ----------------------------------------
- Decompiled bytecode from the incorrect working method (partial):
- ------------------------------
- ; BugSwap.class (partial view of the main() method)
- ; int a = 10, b = 20;
- bipush 10 ; Push 10 into stack (Int)
- istore_1 ; Store into 1st variable (Int)
- bipush 20 ; Push 20 into stack (Int)
- istore_2 ; Store into 2nd variable (Int)
- ; a ^= (b ^= (a ^= b));
- iload_1 ; Load from 1st variable (Int)
- iload_2 ; Load from 2nd variable (Int)
- iload_1 ; Load from 1st variable (Int)
- iload_2 ; Load from 2nd variable (Int)
- ixor ; XOR (Int)
- dup ; Duplicate top operand into stack
- istore_1 ; Store into 1st variable (Int)
- ixor ; XOR (Int)
- dup ; Duplicate top operand into stack
- istore_2 ; Store into 2nd variable (Int)
- ixor ; XOR (Int)
- istore_1 ; Store into 1st variable (Int)
- ; Results:
- ; a = 0
- ; b = 10
- ;
- ; Incorrect!
- ----------------------------------------
- Decompiled bytecode from the correct working method (partial):
- ------------------------------
- ; AlternativeSwap.class (partial view of the main() method)
- ; int a = 10, b = 20;
- bipush 10 ; Push 10 into stack (Int)
- istore_1 ; Store into 1st variable (Int)
- bipush 20 ; Push 20 into stack (Int)
- istore_2 ; Store into 2nd variable (Int)
- ; a ^= b;
- iload_1 ; Load from 1st variable (Int)
- iload_2 ; Load from 2nd variable (Int)
- ixor ; XOR (Int)
- istore_1 ; Store into 1st variable (Int)
- ; b ^= a;
- iload_2 ; Load from 2nd variable (Int)
- iload_1 ; Load from 1st variable (Int)
- ixor ; XOR (Int)
- istore_2 ; Store into 2nd variable (Int)
- ; a ^= b;
- iload_1 ; Load from 1st variable (Int)
- iload_2 ; Load from 2nd variable (Int)
- ixor ; XOR (Int)
- istore_1 ; Store into 1st variable (Int)
- ; Results:
- ; a = 20
- ; b = 10
- ;
- ; Correct!
- ----------------------------------------
- Decompiled bytecode and edited from the former incorrect working method (partial):
- ------------------------------
- ; EditedBugSwap.class (partial view of the main() method, which is edited)
- ; int a = 10, b = 20;
- bipush 10 ; Push 10 into stack (Int)
- istore_1 ; Store into 1st variable (Int)
- bipush 20 ; Push 20 into stack (Int)
- istore_2 ; Store into 2nd variable (Int)
- ; a ^= (b ^= (a ^= b));
- iload_1 ; Load from 1st variable (Int)
- iload_2 ; Load from 2nd variable (Int)
- ixor ; XOR (Int)
- dup ; Duplicate top operand into stack
- istore_1 ; Store into 1st variable (Int)
- iload_2 ; Load from 2nd variable (Int)
- ixor ; XOR (Int)
- dup ; Duplicate top operand into stack
- istore_2 ; Store into 2nd variable (Int)
- iload_1 ; Load from 2nd variable (Int)
- ixor ; XOR (Int)
- istore_1 ; Store into 1st variable (Int)
- ; Results:
- ; a = 20
- ; b = 10
- ;
- ; Correct!
- ----------------------------------------
- Conclusion:
- ------------------------------
- Loading the old values in the first place may work correctly,
- if the stack values are synced with the variables,
- otherwise you may end up using the incorrect values within the stack,
- because the variables are being manipulated in runtime,
- hence the alternative code (3rd one) works as intended.
Advertisement
Add Comment
Please, Sign In to add comment