【问题标题】:C++ volatile member functionsC++ 易失性成员函数
【发布时间】:2011-06-17 03:17:55
【问题描述】:
class MyClass
{
    int x, y;
    void foo() volatile {
        // do stuff with x
        // do stuff with y
    }   
};

我需要将xy 声明为volatile 还是将所有成员变量自动视为volatile

我想确保编译器不会将“带有x 的东西”重新排序为“带有y 的东西”。

编辑: 如果我将普通类型转换为 volatile 类型会发生什么?这会指示编译器不要重新排序对该位置的访问吗?我想在特殊情况下将普通变量传递给参数为 volatile 的函数。我必须确保编译器不会通过之前或之后的读写重新排序该调用。

【问题讨论】:

标签: c++ volatile member-functions


【解决方案1】:

标记一个成员函数volatile就像标记它const;这意味着接收者对象被视为被声明为volatile T*。因此,任何对xy 的引用都将被视为在成员函数中读取volatile。而且volatile对象只能调用volatile成员函数。

也就是说,如果您确实希望所有对它们的访问都被视为volatile,那么您可能需要标记xy volatile

【讨论】:

    【解决方案2】:

    不必显式声明成员变量..

    来自标准文档9.3.2.3

    类似地,volatile 语义 (7.1.6.1) 在访问对象及其非静态时应用于 volatile 成员函数 数据成员。

    【讨论】:

      【解决方案3】:

      以下代码:

      #include <iostream>
      
      class Bar
      {
          public:
      
              void test();
      };
      
      class Foo
      {
          public:
      
              void test() volatile { x.test(); }
      
          private:
      
              Bar x;
      };
      
      int main()
      {
          Foo foo;
      
          foo.test();
      
          return 0;
      }
      

      使用 gcc 编译时引发错误:

      main.cpp: In member function 'void Foo::test() volatile':
      main.cpp:14:33: error: no matching function for call to 'Bar::test() volatile'
      main.cpp:7:8: note: candidate is: void Bar::test() <near match>
      

      由于volatile 实例不能调用non-volatile 方法,我们可以假设,是的,xy 在方法中将是volatile,即使@987654328 的实例@ 未声明 volatile

      注意:如果需要,您可以使用 const_cast&lt;&gt; 删除 volatile 限定符;但是要小心,因为就像const 一样,在某些情况下这样做会导致未定义的行为。

      【讨论】:

      • 如果我对此有误,请纠正我,但 volatile 函数的语义不像 const 函数那样,因为您可以在非易失性对象上调用 volatile 函数,但不能调用非易失性函数来自 volatile 对象?
      • @ereOn- 在g++ 中的快速测试表明您确实可以从 on-volatile 对象调用volatile 成员函数。 volatile std::strings之所以没用,是因为如果字符串本身是volatile,则只能调用volatile的成员函数,其中没有。标准的 $4.4.1 阐明了您可以将 T* 隐式转换为 volatile T*,并且 $9.3.1.3 表示 volatile 限定符会影响 this 指针,这表明如果您有一个类型为 @987654341 的对象@,T* 类型的 this 指针可以转换为 volatile T* 用于调用。
      • @templatetypedef:我颠倒了逻辑(现在才早上 7 点;我还需要睡觉;))。谢谢,现在已经修好了。您可以从volatilenon-volatile 实例调用volatile 方法。但是,如果您的实例是 volatile,您将无法调用 non-volatile 方法。
      • @ereOn:所以,正如 templatetypedef 所说,它与 const 完全相同。相关部分当然不是 g++,但标准:第 4.4.1 条似乎向我表明,thisT*volatile T* 的必要隐式转换是完全合法的。另请注意,9.3.2.4 明确指出,如果您调用它的对象表达式“与成员函数一样 cv 限定或更少 cv 限定”,则可以调用 cv 限定函数。在这方面constvolatile 没有区别。
      • 至于转换:如果原始对象实际上被定义为 volatile,并且您将这个对象或其成员之一作为左值(基本上,在赋值的左侧)作为非volatile,标准的第 7.1.5.1.7 条表示程序行为未定义。不要这样做,即使它在当前测试数据上与当前编译器的当前版本一起使用。 AFAICS,演员表对于只读访问来说是可以的,就像const一样。
      【解决方案4】:

      所以使用原来的例子:

      class MyClass
      {
          int x, y;
          void foo() volatile {
              // do stuff with x
              // do stuff with y
              // with no "non-volatile" optimization of the stuff done with x, y (or anything else)
          }   
          void foo() {
              // do stuff with x
              // do stuff with y
              // the stuff done with x, y (and anything else) may be optimized
          } 
      };
      

      【讨论】:

        猜你喜欢
        • 2016-03-24
        • 1970-01-01
        • 2013-09-08
        • 2018-08-09
        • 1970-01-01
        • 2023-03-13
        • 2018-10-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多