如问题所示: 让我们说我有一小段这样的代码:
1, 2, 3
使用 #include <iostream>
using namespace std;
struct foo {
int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
编译,结果证明g++ -g -O2
初始化已经过优化。
然而那个:
x
调用构造函数。
如果我尝试使用代码中的变量(即 #include <iostream>
using namespace std;
struct foo {
volatile int a;
foo() : a(12) {};
};
int
main()
{
volatile foo x;
return 0;
}
),则两种情况下的汇编输出都是等效的。
我是否有以下权利:
在第一种情况下,根本无法访问结构,因此它会完全被优化。
在第二个中,struct的字段被指示为在构造期间也可以改变的字段,因此无论如何都会调用foo()。
添加了:
我试过摆弄上面的代码:
调用cout << foo.a << endl;
之类的东西按预期工作,它实际上发生而不是在优化期间被结果删除/替换,因此看起来volatile实际上是继承的,但ctor在这种奇怪的行为(或者至少在开始时是意外的)方式。
编辑编号2:
我用clang和MSVC检查它,它的行为与gcc相同。
答案 0 :(得分:2)
我的理解如下(我不确定):
在C ++ volatile
关键字中强制编译器不要优化看似冗余的加载和存储到内存,即如果你有这样的示例代码:
int x = 5;
x = 6;
不会更改为:
int x = 6;
这是因为x
可能指向内存中的某个地址,这是其他人读取的,而您实际上并未在程序中读取它(想象您通过USART发送了一些配置微控制器通过写入某个存储器地址,并且微控制器从该地址读取它的配置 - 如果编译器要优化对该存储器的写入,则整个程序会发生故障。
必须记住的另一件事是,当一个类的实例用volatile
说明符声明时,它的成员继承这个说明符(正如Igor Tandetnik在评论中指出的,指的是C ++标准)。但这不是全部真相,因为为了获得volatile
行为,您必须调用标记为volatile
的成员函数 - 类似于将成员函数标记为const
(请看这个:http://www.devx.com/tips/Tip/13671)。因为AFAIK ctors / dtors不能用volatile
关键字标记(如在Defining volatile class object中),所以你必须稍微改变你的代码(也许从ctor中调用volatile成员函数会做的事情,但是这个只是一个猜测。)