繁体   English   中英

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

[英]C++ volatile object, nonvolatile member

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

  #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;
  }   

调用构造函数。

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

我是否得到以下权利:

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

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

补充:我试过摆弄上面的代码:调用像while(foo.a--); 按预期工作,它实际上发生而不是在优化期间被结果删除/替换,因此看起来挥发性实际上是继承的,但是ctor在这种奇怪的(或者至少在第一次意外)方式中表现。

编辑2:

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

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

在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关键字标记(如在定义volatile类对象中 ),所以你必须稍微改变你的代码(也许从ctor中调用volatile成员函数会做的事情,但这只是猜测) 。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM