Tuesday, July 29, 2008

Java vs C++

Life at Amazon.com has been pretty good except for a few intricately hidden bugs which at times are difficult to swat! Here's one nice bug, oops! (no pun intended) I wouldn't call it a bug. Fully geared up for the task given to me this morning, the keyboard had a bad day until I had to do a swap...

Well, what's there in a swap after all ? Just out of college, you do tend to show a lot of gimmicks, don't you ? I too, am a faithful follower of the policy and wrote

x^=(y^=(x^=y)); where x,y are integers.
Now, compile successful, build successful, Yaaaaaaaaay!!! - it's a 1000 line code, so the celebration kind of justified :-). But wrong answer :-(
So, I get down to the debugging stage, I do a

while( 1 ) { debug; }


After spending a lot of time (no way, am going to tell you how much I spent :P), I realised, there was a bug in my swap code!!. Can you imagine ? It was such a common question, almost appeared in every single CS written paper. But, this is Java dear :-)

Googling Java specifications lead me to a new finding:
"A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once"

Hence, whatever assignment happens in (x^=y) has almost nil effect w.r.t this statement!!!! This one-liner won't work

To be more precise, C++ rule states
"A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1"

Step 1: x = x^y;
Step 2: y = y ^ ( x^y) = x;
Step 3: x = ('x' computed from Step1) ^ (y computed from Step2 ) =
= (x ^y)^x
=y

PS: I could have definitely explained it better using opcodes, but I want to keep it as simple as possible. As long as the meaning is conveyed, I am happy :-)

Let's see what Java does
Step 1: x = x^y;
Step 2: y = y ^ ( x^y) = x;
Step 3: x = (x) ^ (y computed from Step2 ) =
= x^x
= 0

This result is attributing purely towards the wicked statement at the end :-)

At the EOD, I said "Thank God, there are no #defines in Java, God knows how many gimmicks I would have shown with that and how many screeching bugs would have been inside!!"

I want to look at the bytecodes generated, googling how to look at it now:-). My 1st lesson, well learnt :D


8 comments:

Karthik Swaminathan said...

At last (Amazon-)Coder is back with a blog entry!! The post is in strict accordance with his name also ;)

Vivek said...

Been due for quite sometime :-). How do I keep track of your blog ? I am new to this blogging world u see :)

Anonymous said...

I think you should explain the working of the statement in C/C++ first and then compare it with its working in Java. Your Java explanation also needs some elaboration. I am assuming you aimed at making each blog entry a valuable reference for fellow programmers. So that calls for a more responsible explanation!

Vivek said...

Is it ok ? :-)

Anonymous said...

Nope. I still don't understand the differential treatment meted out to the last 'x' substitution. Aren't most recently computed values of the expression plugged in to obtain the result? Why was the last 'x' valued as 'x' as opposed to 'x^y'? I think you can clarify this on your comments. You don't have to keep modifying the blog entry.

Vivek said...

Read the java spec that I have mentioned, everything should fall in place :-)

Anonymous said...

By java spec did you mean the stepwise psuedo-code? If so, I was exactly questioning that. Why is the recently computed value of 'x' not applied in the last step? Or should we not question it and safely apply your 3 step algorithm for future evaluation of such expressions?

Vivek said...

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once