Re: [GCC 4.3] Strange -O2 optimization issue

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

 



Brian Dessent wrote:
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:

Brian,

Good to hear I was close ;-)

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.
> [...]

Thank you very much for in-depth explanation of the problem.
It was greatly helpful.

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.

I fixed my code with memcpy option.

-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>

-Wstrict-aliasing=2 does not warn about aliasing rules broken in that line with the case, but -Wstrict-aliasing=1 does. Yes, I've read the manual and understand it why.

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.

Right, I suspected UB from the beginning of my investigation.

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.

Very good point :-)

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


Thank you very much again!

Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
Charter Member of OSGeo, http://osgeo.org

[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