涉及优化器的局部变量构造和破坏

时间:2011-03-10 09:35:59

标签: c++ optimization volatile allocation destruction

如果我有这段代码:

class A { ... };
class B { ... };

void dummy()
{
    A a(...);
    B b(...);
    ...
}

我知道变量ab将以反向分配顺序销毁(b将首先销毁,然后a);但我可以确定优化器永远不会交换ab的分配和构造吗?或者我必须使用volatile强制执行它?

4 个答案:

答案 0 :(得分:6)

唯一的保证是volatile构造的任何可观察的副作用(即对a对象的读写和对I / O函数的调用)都会在任何可观察到的副作用之前发生b的构造,a所需的b的任何副作用都将在需要之前发生。

很难想象为什么你需要比这更严格的顺序,但是在volatile的任何部分初始化之前,制作对象a将确保b完全初始化,尽管有些<{1}}完成之前,构造函数中的代码仍然可能发生。

答案 1 :(得分:3)

您唯一可以确定的是a的构建和分配将在b之前。只要您将语句与;分开,无论优化如何,它们都将按顺序执行。

volatile不会改变它,它的作用是阻止编译器在访问之间缓存值。

答案 2 :(得分:0)

好的,我在标准中发现了这样的陈述,但我对其他人的答案感到有些困惑。

  

通话中的每一次评估   功能(包括其他功能   (除非另有说明)   特别是在之前或之后测序   执行机构的   被称为函数是不确定的   按顺序排序   执行被调用的函数。 (换句话说,函数执行不会相互交错。)

它只能确保函数调用不相互交错,但函数是不确定的顺序,这意味着,

  

评估A和B是   不确定地排序   A在B或B之前排序   在A之前排序,但确实如此   未指明哪个。

答案 3 :(得分:0)

我遇到了这个问题。优化器对代码重新排序。为了防止重新排序,我建议两种方式:

1)将对象封装在结构中:

class A { ... };
class B { ... };

struct C {
     A a;
     B b;
};

void dummy()
{
    C c;
}

2)将变量放入块运算符中:

class A { ... };
class B { ... };

void dummy()
{
    A a;
    {
        B b;
    }
}