Something odd I noticed today:
#include <CoreServices/CoreServices.h>
int main( int argc, char** argv )
{
UInt32 a = 0;
a += (double) -1;
printf( "%d\n", a );
return a;
}
this code prints 0 on an Intel Mac, but prints -1 on a PowerPC. So, essentially the PPC seems to just overflow, but the Intel CPU seems to refuse to go below 0.
I guess it’s a matter of definition, but does anyone know the official reasoning behind this? I.e. know whether the C standard or Intel/IBM/Motorola specify that this should be so?
Just curious…

Yeah, this is an undefined behavior in the C family of languages because you’re casting into a type that is incapable of representing the value. Here’s the text from C99, just to pick a standard:
“When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.”
The value of the integral part is negative, so it can’t be represented in a UInt32… thus the behavior is undefined. It just so happens that the compiler’s PowerPC backend does it one way (overflow), and the x86 backend does it another (pinning to zero). Neither is wrong; they’re just different.
Interesting, though. I knew about the problem but not that OSX did it differently for the two platforms. That’s sure to be a ‘gotcha’ for porting code over.
I told GCC to generate assembler for this code snippet, and wow! the assembler for PowerPC is *dense*. I’m long out of practice reading assembler, and most of that was x86, so I guess I have some brushing up to do. :-)
If you get an opportunity, can you feed this code snippet through gcc -S on an Intel Mac? I’m curious to see if this behavior you report is due to differences in the generated code, or differences in how the two architectures behave.
@Drew: Thanks, I’d suspected it was one of those undefined spots, but offhand I couldn’t find anything.
@Craig: I’ll see if I get around to it.