Why does (unsigned short)-1.3 == 0 and not 65535? (But only if optimizing with GCC 4.x)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux