如果我有这段代码:
class A { ... };
class B { ... };
void dummy()
{
A a(...);
B b(...);
...
}
我知道变量a
和b
将以反向分配顺序销毁(b
将首先销毁,然后a
);但我可以确定优化器永远不会交换a
和b
的分配和构造吗?或者我必须使用volatile
强制执行它?
答案 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;
}
}