C++ 易失性成员函数

Posted

技术标签:

【中文标题】C++ 易失性成员函数【英文标题】:C++ volatile member functions 【发布时间】: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 的函数。我必须确保编译器不会通过之前或之后的读写重新排序该调用。

【问题讨论】:

相关***.com/questions/2444734/… 【参考方案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
     
;

【讨论】:

以上是关于C++ 易失性成员函数的主要内容,如果未能解决你的问题,请参考以下文章

函数没有易失性。怎么修?

易失性用户定义函数未按预期重新计算(VBA/Excel)

在这个多线程 C++ 代码中是不是需要“易失性”?

将易失性数组转换为非易失性数组

具有易失性和外部数据访问的 C++ 常量正确性

自动重新评估非易失性 UDF