C++ volatile member functions
class MyClass
{
int x, y;
void foo() volatile {
// do stuff with x
// do stuff with y
}
};
Do I need to declare x
and y
as volatile
or will be all member variables treated as volatile
a开发者_运维技巧utomatically?
I want to make sure that "stuff with x
" is not reordered with "stuff with y
" by the compiler.
EDIT:
What happens if I'm casting a normal type to a volatile
type? Would this instruct the compiler to not reorder access to that location? I want to pass a normal variable in a special situation to a function which parameter is volatile. I must be sure compiler doesn't reorder that call with prior or followed reads and writes.
Marking a member function volatile
is like marking it const
; it means that the receiver object is treated as though it were declared as a volatile T*
. Consequentially, any reference to x
or y
will be treated as a volatile
read in the member function. Moreover, a volatile
object can only call volatile
member functions.
That said, you may want to mark x
and y
volatile
anyway if you really do want all accesses to them to be treated as volatile
.
You don't have to declare the member variables explicitly..
From Standard docs 9.3.2.3,
Similarly, volatile semantics (7.1.6.1) apply in volatile member functions when accessing the object and its nonstatic data members.
The following code:
#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;
}
Raises an error upon compilation with 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>
And since a volatile
instance can't call a non-volatile
method, we can assume that, yes, x
and y
will be volatile
in the method, even if the instance of MyClass
is not declared volatile
.
Note: you can remove the volatile
qualifier using a const_cast<>
if you ever need to; however be careful because just like const
doing so can lead to undefined behavior under some cases.
So using the original example:
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
}
};
精彩评论