Mr. Endian Bytes Back
The worse endian bug yet - a definite gem for the ages.
I spent several hours tracking down a ref counting bug in one of our CLR data structures. The following code snippets are boiled down from a much more complicated structure and set of functions.
typedef struct
{
SHORT x;
SHORT y;
} FOO;
void BadCode( FOO foo)
{
InterlockedIncrement( (PLONG)&foo.x );
}
The code actually works just dandy on x86 since the address is always aligned on a 4 byte boundary and, since x86 is little endian, the address &foo.x actually refers to the LSB of x. This particular value in this case will never overflow the 2-byte signed SHORT, so this works as intended.
If you haven't alredy guessed it, on a big endian platform, this actually increments the value of foo.y. Flawlessly. Every single time. Talk about a bugger to find. I noted the problem when I finally stepped over the interlocked operation and actually noticed that the wrong field changed value in the local window of the debugger!
Now the challenge - how do we fix it? We didn't want to use 32bit values since this would eat up storage unnecessarily as this is a structure quite frequently instantiated. So to add a hack upon a hack, we flipped the fields for big endian platforms :O
And put a very large comment next to the hack. :o\
Spoooooooky.