now browsing by month
After only getting 3 hours of sleep yesterday due to me creating the next homework for computer vision and an early morning meeting with my advisor, I learned that all the testing has to be done this week for the paper abstract deadline next week. Oh joy joy. So instead of going home to sleep off the afternoon, I had to do horror of horrors…actual work. However, it was SOOO cold down in the dungeon. Usually it is quite chilly and I’ll wear a light sweater but it was just completely rediculous today. Somebody must have left the AC on manual override or maybe just sucking in 40F air from houtside. Anyhow, there is a giant vent right up and to the left of my workstation. And with the surgeon coming in the following morning, I was going to be working most of the night. So I decided to do something about this infernally powerful AC draft. After several ideas, I came up with a box wedge solution. The only problem? What do I wedge the box against to block the vent? Turns out the solution is to construct a giant stack of boxes. And it worked! Oh the flush of warm success cascaded down on me like the harsh crushing clank of a dropped needle.
So today I heard of a CMU graduate student who was interviewing with Microsoft and they asked him what the result of the following C code would be:
int i = 10; printf(“%d %d %d\n”, i++, i++, ++i);
First off, this is a dumb question to ask a student who is about to graduate with a PhD in robotics. Second, this is utterly retarded code that should be avoided. Third, this question really would only apply to a compiler developer or say if you were interested in seeing how well somebody knows language specifications. Regardless of what this question was supposed to be testing, it is an interesting piece of code. For instance, a first guess might be 10, 11, 13. However, I know the C calling convention specifies arguments are passed in reverse order on the stack. So my guess on the output of this code would be: 11, 11, 13. The acid test however is to run this code. Let’s compile a test program and see what we get:
gcc on Ubuntu: 12, 11, 13
What? This answer doesn’t match up to either guess and makes no sense. Let’s try it on Visual Studio 2005:
VC++ 2005: 12, 11, 13
Well at least the result is consistent if not terribly intuitive. However, just for kicks let’s try release mode:
VC++ 2005 Release: 11, 11, 11
Whoa! What’s going on here? This answer makes even less sense! Not only is this totally unexpected, but we have just lost consistency between the same compiler. This is very very bad. Code should NOT run this differently between debug/release modes. For a complete roundup, let’s try some other compilers:
VC++ 6.0 Debug: 11, 11, 13
VC++ 6.0 Release: 11, 11, 11
gcc on cygwin: 12, 11, 11
Wow, so this is faith shattering. The same piece of code runs totally differently depending on compiler/configuration. What is going on here? Doing some sluething on Google, it turns out the root of the problem is the C/C++ standard leaves the evaluation order of arguments passed to functions unspecified. Also, we are mixing reading and writing variables in the same expression (the ++ operator does both read/write). Again the result is undefined. However, not ONE of the compilers warns about this! In fact, let’s enable all warnings on gcc (-Wall). I now get “warning: no newline at the end of file.” Great! gcc warns about meaningless issues while totally ignoring completely unspecified behavior. So helpful!
Now it might seem this whole thing is academic. After all, who would ever write code as silly as that printf statement? Actually it’s not quite as far fetched as you might think. Let’s take a hypothetical example of saving and updating some records where both functions update and save return an integer error code indicating success/failure:
printf(“Updating records: %d\n; Saving records: %d\n”, records.update(data), records.save());
Oops, which one gets executed first? Did you save the record before or after updating it? Major oops. Moral of the story: knowing language specifications can help you avoid very subtle bugs that not even the compiler will warn you about. Also you can make a fool out of your interviewer by proving more knowledgeable than him when he asks dumb questions (this probably won’t get you hired though).
Some good references on the subject: