This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[GCC 4.3] Strange -O2 optimization issue


Hello,

I'm experiencing a strange problem while building a small program
using GCC 4.3.1 (Debian, Lenny) with -O2 optimization.
The program is a simple hash generator from 2D point,
using high and low word of a coordinate (object of double type).
I include a small test program [1]

Here are 3 test cases that differ in optimization flag only

$ g++ -W -Wall -o bar bar.cpp
$ ./bar
1073741824
1073741824
1073741824
1073741824
1073741824

$ g++ -O1 -W -Wall -o bar bar.cpp
$ ./bar
1073741824
1073741824
1073741824
1073741824
1073741824

$ g++ -O2 -W -Wall -o bar bar.cpp
$ ./bar
136623933
1073741824
1073741824
1073741824
1073741824


Why the first value printed is different (136623933) in the 3rd test case.

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?

I'd be also very thankful for references in C/C++ standards
explaining this behavior of GCC.

I've noticed, that if I uncomment the printf in HashDouble function,
third test case (-O2 optimization) returns all the same values.

Perhaps my test program is buggy, for example I suspect the cast in HashDouble function. Is it?

I run my tests cases using GCC 4.0.1 and the problem
does not leak there.

Thanks in advance for your help!



[1] Test program

// bar.cpp ////////////////////////////////////////////////
#include <cstdio>

struct Point
{
public:
    double x;
    double y;
    double getX() const { return x;}
    double getY() const { return y;}
};
static unsigned long HashDouble(double* pdfVal)
{
    unsigned int* pnValue = (unsigned int*)pdfVal;

// printf("%p\n", pnValue); // Seems to fix the problem

    return pnValue[0] ^ pnValue[1];
}
static unsigned long HashPoint(const Point* point)
{
    double x = point->getX();
    double y = point->getY();
    return HashDouble(&x) ^ HashDouble(&y);
}
int main()
{
    Point* po = new Point();
    po->x = 1;
    po->y = 2;

    for (int i = 0; i < 5; ++i)
    {
        std::printf("%lu\n", HashPoint(po));
    }
    delete po;
    return 0;
}
///////////////////////////////////////////////////////////

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]