为什么g ++优化了以下代码的关键部分?

Sve*_*ven 2 c++ g++ compiler-optimization

以下代码导致程序崩溃,因为

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;
    }
Run Code Online (Sandbox Code Playgroud)

以某种方式优化

void fractalizeSegment() {
    next = &a1;
}
Run Code Online (Sandbox Code Playgroud)

在p0 = {x = 0,y = 0,next = 0x7fffffffe100}上调用该方法,其指向p1 = {x = 1,y = 0,next = 0x0}.

通过分析调试器中的程序,我发现当我在方法fractalizeSegment时:

a1 = {x = 6.9533558075099091e-310, y = 6.9533558075098597e-310, next = 0x7fffffffe190}
Run Code Online (Sandbox Code Playgroud)

在地址a1.next中有

a2 = {x = 6.9533558074508189e-310, y = 4.9406564584124654e-324, next = 0x34}.
Run Code Online (Sandbox Code Playgroud)

试图遵循(*a2.next).next会导致分段错误.

为什么g ++会像这样优化我的代码?我该怎样预防呢?

我发现当前的解决方法是打印出a1,a2和a3的值,这阻止了优化.

rod*_*igo 7

a1是一个本地自动变量,在从函数返回时将被销毁,因此之后的任何使用都*next将是未定义的.编译器认为你肯定不会使用这些值,所以为什么要费心计算它们.

您可能想要a1在堆中创建:

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

或许也a2a3应动态分配的,而是取决于执行Point,你没有显示.

并记住delete在某处分配的对象.

  • 你真的在"in"vs"on"上狡辩吗?后者比前者更惯用,更准确. (2认同)