Why does (unsigned short)-1.3 == 0 and not 65535? (But only if optimizing with GCC 4.x)
Jack Lloyd
lloyd@randombit.net
Thu Mar 25 04:14:00 GMT 2010
This code does something unexpected for me:
#include <stdio.h>
int main()
{
double d = -1.3;
unsigned short x = (unsigned short)d;
printf("%d\n", x);
}
With Visual C++ and GCC 3.4.6, it outputs 65535 (ie -1 cast to an
unsigned short). With GCC 4.x, it also outputs 65535, _unless_
optimizations are on (specifically something enabled by -O1, I haven't
traced it to the specific option), in which case it outputs 0. This is
all on x86/x86-64 (same behavior for both AFAICT).
First, can someone explain why this is happening? This behavior really
broke my mental model of how C rounding/casting works.
Secondly, can someone tell me if there is a warning I can use to tell
me when this is happening? The code compiles cleanly with (or without)
optimizations using "-Wall -Wextra -Wconversion". In this specific
case, I can get the behavior I want using
(unsigned short)(int)d;
but I'm in the process of porting a large code base from Visual C++ to
GCC (the original source of this problem) and am worried that similiar
rounding traps will remain hidden elsewhere until a highly
innopportune moment.
Please CC me on any replies as I am not subscribed to the list.
Thanks,
Jack
More information about the Gcc-help
mailing list