2011-01-28 141 views
27
class MyClass 
{ 
    int x, y; 
    void foo() volatile { 
     // do stuff with x 
     // do stuff with y 
    } 
}; 

是否需要声明'x'和'y'为volatile或将所有成员变量视为volatile自动处理?C++ volatile成员函数

我想确保“stuff with'x'”不会被编译器的“stuff with y”重新排序。

编辑: 如果我将正常类型转换为易失性类型,会发生什么?这是否会指示编译器不重新排序访问该位置?我想在特殊情况下将一个普通变量传递给一个参数是volatile的函数。我必须确定编译器不会重新排序那个调用的先前或之后的读写。

+2

大问题。 – 2012-09-09 15:36:40

+0

相关的http:// stackoverflow。com/questions/2444734/what-is-volatile-member-function-in-c – 2016-09-09 00:09:25

回答

22

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

这就是说,你可能想要标记xyvolatile无论如何,如果你真的希望所有访问他们被视为volatile

4

下面的代码:

#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,即使MyClass的实例未被声明为volatile

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

6

必须显式声明的成员变量..

从标准文档9.3.2.3

同样,可变语义(7.1.6.1)在访问对象及其非静态数据成员时应用于volatile成员函数。

1

因此,使用原来的例子:

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