简体   繁体   English

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

[英]C++ volatile object, nonvolatile member

As in the question: let's say I have a small piece of code like this: 在问题中:假设我有一小段这样的代码:

  #include <iostream>
  using namespace std;

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

  int
  main()
  {
      volatile foo x;
      return 0;
  }   

compiled with g++ -g -O2 it turns out, that x initialization is optimized away. g++ -g -O2编译,结果证明x初始化是最优化的。

That one however: 然而那个:

  #include <iostream>
  using namespace std;

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

  int
  main()
  {
      volatile foo x;
      return 0;
  }   

calls the constructor. 调用构造函数。

If I try to use the variables inside the code, (ie. cout << foo.a << endl; ) the assembly output is equivalent in both cases. 如果我尝试使用代码中的变量,(即cout << foo.a << endl; ),汇编输出在两种情况下都是等效的。

Do I get the following right, that: 我是否得到以下权利:

In the first case, there's no access to the struct at all, so it gets optimized away completely. 在第一种情况下,根本无法访问结构,因此它完全被优化掉了。

In the second one, struct's field is indicated as the one possible to change also during the construction and for that reason foo() is called no matter what. 在第二个中,struct的字段被指示为在构造期间也可以改变的字段,因此无论如何都调用foo()。

Added: I've tried fiddling with the above code: calling things like while(foo.a--); 补充:我试过摆弄上面的代码:调用像while(foo.a--); works as expected, it actually happens instead of being deleted/replaced by result during optimization, thus it seems the volatile is actually inherited, yet the ctor behaves in this strange (or at least unexpected at first) way. 按预期工作,它实际上发生而不是在优化期间被结果删除/替换,因此看起来挥发性实际上是继承的,但是ctor在这种奇怪的(或者至少在第一次意外)方式中表现。

EDIT number 2: 编辑2:

I checked it with clang and MSVC and it behaves the same way as in gcc. 我用clang和MSVC检查它,它的行为与gcc相同。

My understanding is as follows (and I am not sure about it): 我的理解如下(我不确定):

In C++ volatile keyword forces compiler not to optimize seemingly redundant loads and stores to memory, ie if you have such example code: 在C ++中, volatile关键字强制编译器不要优化看似冗余的加载和存储到内存,即如果你有这样的示例代码:

int x = 5;
x = 6;

It will not be changed to: 它不会改为:

int x = 6;

This is because x could be pointing to some address in memory, that is read by others, while you don't read it really in your program (imagine that you are sending some configuration over USART to microcontroller by writing to certain memory address, and the microcontroller reads it's configuration from that address - if compiler was to optimize writes to this memory, then whole program would malfunction). 这是因为x可能指向内存中的某个地址,这是其他人读取的,而您在程序中并未真正读取它(想象您通过写入某个内存地址,通过USART将一些配置发送到微控制器,并且微控制器从该地址读取它的配置 - 如果编译器要优化对该存储器的写入,则整个程序将发生故障)。

Another thing that one must remember is that when instance of a class is declared with volatile specifier, then its members inherit this specifier (as Igor Tandetnik pointed out in comment, referring to C++ Standard). 必须记住的另一件事是,当一个类的实例用volatile说明符声明时,它的成员继承这个说明符(正如Igor Tandetnik在评论中指出的那样,指的是C ++标准)。 But this is not the whole truth, because in order to get volatile behaviour, you would have to call member functions, that are marked as volatile - similar to marking member function as const (please see this: http://www.devx.com/tips/Tip/13671 ). 但这不是全部真相,因为为了获得volatile行为,你必须调用标记为volatile成员函数 - 类似于将成员函数标记为const (请参见: http://www.devx。 com / tips / Tip / 13671 )。 Because AFAIK ctors/dtors cannot be marked with volatile keyword (as in Defining volatile class object ), you would have to change your code a bit (perhaps invoking volatile member function from within ctor would do the thing, but this is only a guess). 因为AFAIK ctors / dtors不能用volatile关键字标记(如在定义volatile类对象中 ),所以你必须稍微改变你的代码(也许从ctor中调用volatile成员函数会做的事情,但这只是猜测) 。

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

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