The example below copies a float from one location to the next. When compiling with -O1 or less using 4.1.2, z equals *baz, and the program displays "ok, no bug." When compiling with -O2 or greater, z doesn't equal *baz, and the program prints "whoah: 23423.234375 should equal 8523244312281203485966336.000000". Also of note, when one prints the value of q before defining *baz using -O2, the value of *baz changes to 0.00000. This problem did not occur using gcc 4.0.1 with -O2.
#include <stdio.h> #include <stdint.h> int main(int argc, char **argv) { float z = 23423.23424; uint32_t* foo = (uint32_t*)&z; uint8_t zbuf[4] = {0,0,0,0}; zbuf[3] = ((*foo) & 0x000000ffL); zbuf[2] = ((*foo) & 0x0000ff00L) >> 8; zbuf[1] = ((*foo) & 0x00ff0000L) >> 16; zbuf[0] = ((*foo) & 0xff000000L) >> 24; uint32_t q = (((uint32_t)zbuf[0] << 24) | ((uint32_t)zbuf[1] << 16) | ((uint32_t)zbuf[2] << 8) | ((uint32_t)zbuf[3])); float *baz = (float*)&q; if (z == *baz) fprintf (stderr, "okay, no bug\n"); else fprintf (stderr, "whoah: %f should equal %f\n", z, *baz); return 0; } -- Summary: optimization of bit-shifts leads to strange results Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: blake dot tregre at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34552