Sven Sven - 3 years ago 100
C++ Question

Why does g++ optimize out a critical section of the following code?

The following code causes a crash in my program, because

void fractalizeSegment() {
// Assume next != NULL
double deltaX = next->x - x;
double deltaY = next->y - y;

// Add 3 new points labeled a1, a2, a3 from this to next
Point a3(x + 2.0*deltaX/3.0, y + 2.0*deltaY/3.0, next);
double sqr3 = std::sqrt(3.0);
Point a2(x + deltaX/2.0 - sqr3*deltaY/2.0,
y + deltaY/2.0 + sqr3*deltaX/2.0,
&a3);
Point a1(x + deltaX/3.0, y + deltaY/3.0, &a2);

next = &a1;
}


Is somehow optimized to

void fractalizeSegment() {
next = &a1;
}


The method is called on p0 = {x = 0, y = 0, next = 0x7fffffffe100},
which point to p1 = {x = 1, y = 0, next = 0x0}.

By analyzing the program in the debugger I found that when I'm in the method fractalizeSegment:

a1 = {x = 6.9533558075099091e-310, y = 6.9533558075098597e-310, next = 0x7fffffffe190}


In address a1.next there is

a2 = {x = 6.9533558074508189e-310, y = 4.9406564584124654e-324, next = 0x34}.


Trying to deference (*a2.next).next causes a segmentation fault.

Why does g++ optimize my code like this? How can I prevent it?

The current workaround I found was printing out the values of a1, a2, and a3,
this prevented the optimization.

Answer Source

a1 is a local automatic variable that will be destroyed upon returning from the function, so any use of *next after that will be undefined. The compiler thinks that surely you will not use those values so why bother computing them.

You probably want to create a1 in the heap:

next = new Point(x + deltaX/3.0, y + deltaY/3.0, &a2); //no need of a1.

And remember to delete it somewhere.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download