C++易失性对象,非易失性成员

ala*_*ner 9 c++ volatile

在问题中:假设我有一小段这样的代码:

  #include <iostream>
  using namespace std;

  struct foo {
      int a; 
      foo() : a(12) {};
  };  

  int
  main()
  {
      volatile foo x;
      return 0;
  }   
Run Code Online (Sandbox Code Playgroud)

g++ -g -O2它编译结果证明,x初始化是最优化的.

然而那个:

  #include <iostream>
  using namespace std;

  struct foo {
      volatile int a; 
      foo() : a(12) {};
  };  

  int
  main()
  {
      volatile foo x;
      return 0;
  }   
Run Code Online (Sandbox Code Playgroud)

调用构造函数.

如果我尝试使用代码中的变量,(即cout << foo.a << endl;),在两种情况下,程序集输出都是等效的.

我是否得到以下权利:

在第一种情况下,根本无法访问结构,因此它完全被优化掉了.

在第二个中,struct的字段被指示为在构造期间也可以改变的字段,因此无论如何都调用foo().

补充:我试图摆弄上面的代码:调用类似于while(foo.a--);预期的工作,它实际上发生而不是在优化期间被结果删除/替换,因此似乎volatile实际上是继承的,但ctor在这种奇怪的行为(至少或至少意外的方式.

编辑2:

我用clang和MSVC检查它,它的行为与gcc相同.

小智 2

我的理解如下(我也不确定):

在 C++ 中,volatile关键字强制编译器不要优化看似冗余的加载和存储到内存,即如果您有这样的示例代码:

int x = 5;
x = 6;
Run Code Online (Sandbox Code Playgroud)

不会更改为:

int x = 6;
Run Code Online (Sandbox Code Playgroud)

这是因为x可能指向内存中的某个地址,该地址被其他人读取,而您并没有在程序中真正读取它(想象一下您通过写入特定内存地址通过 USART 将一些配置发送到微控制器,并且微控制器从该地址读取它的配置 - 如果编译器要优化对此内存的写入,那么整个程序将出现故障)。

必须记住的另一件事是,当使用说明volatile符声明类的实例时,其成员继承此说明符(正如 Igor Tandetnik 在评论中指出的那样,参考 C++ 标准)。但这并不是全部事实,因为为了获得volatile行为,您必须调用标记为volatile- 类似于将成员函数标记为const(请参阅: http: //www.devx.com/tips /提示/13671)。因为 AFAIK ctors/dtors 不能用volatile关键字标记(如定义 volatile 类对象),所以您必须稍微更改代码(也许从 ctor 中调用 volatile 成员函数可以做到这一点,但这只是一个猜测)。