Mateusz Loskot wrote: > Why the first value printed is different (136623933) in the 3rd > test case. Your suspicion is correct, as this violates the ISO C aliasing rules: > static unsigned long HashDouble(double* pdfVal) > { > unsigned int* pnValue = (unsigned int*)pdfVal; You're accessing a variable of type double through a pointer of type unsigned int. For the purposes of optimization the compiler is allowed to assume that values of type double will only be accessed through variables of type double, and thus it can assume that pdfVal and pnValue can't refer to the same thing. It may seem nonsensical in this instance that it would assume that, but it's still legal for the compiler to do so. And being able to make this assumption allows for interesting optimizations, for example consider something like: typedef struct { int size; float *data; } foo; void bar (foo *src, foo *dest) { for (int i = 0; i < src->size; i++) dest->data[i] += src->data[i]; } In this example all the stuff happening in the loop with the data arrays involves floats so the compiler can prove to itself that src->size (an integer) cannot change, and thus it can hoist it out of the loop so that it only need be computed once. This comes up in code that uses STL containers for example. (This example was brought up in the following thread which has more to say on the topic: <http://gcc.gnu.org/ml/gcc/2006-11/threads.html#00877>.) If you want to rewrite your code in a conformant way you can use a union or memcpy; or you can disable strict aliasing with -fno-strict-aliasing. -Wstrict-aliasing is intended to warn about things like this, but since it's included in -Wall it obviously failed to warn in your case. There are several levels of -Wstrict-aliasing though, so you may need to turn to -Wstrict-aliasing=2 to catch this case. See the docs for details: <http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstrict_002daliasing-312> As to why only the first value printed differs, or why taking the address of pnValue changes the outcome, or why older versions of gcc worked fine: that is the general nature of undefined behavior. It can take on any form whatsoever, from working perfectly, to failing spectacularly, or anywhere in between. All rules are out the window. It is best not to try to understand the effects or outcome but rather to understand how to fix the code so that it is no longer undefined. > Also, could anyone enlighten me and explain what kind of optimization is > applied when -O2 flag is used, so the first value printed is different? To quote the manual: <http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fstrict_002daliasing-698> The -fstrict-aliasing option is enabled at levels -O2, -O3, -Os. > I'd be also very thankful for references in C/C++ standards > explaining this behavior of GCC. See section 6.5.7 of the C99 standard. Brian