class MyClass
{
int x, y;
void foo() volatile {
// do stuff with x
// do stuff with y
}
};
我是否需要将x
和y
声明为volatile
或将所有成员变量自动视为volatile
?
我想确保“编译x
的内容”不会被编译器的“y
”重新排序。
编辑:
如果我将普通类型转换为volatile
类型会发生什么?这是否会指示编译器不重新排序对该位置的访问?我想在特殊情况下将一个普通变量传递给一个参数是volatile的函数。我必须确保编译器不会使用先前或后续的读写操作重新排序该调用。
答案 0 :(得分:30)
标记成员函数volatile
就像标记const
;这意味着接收器对象被视为声明为volatile T*
。因此,对x
或y
的任何引用都将被视为成员函数中的volatile
读取。此外,volatile
对象只能调用volatile
个成员函数。
也就是说,如果您确实希望对其进行的所有访问都被视为x
,则可能需要标记y
和volatile
volatile
。
答案 1 :(得分:8)
您不必须明确声明成员变量..
来自标准文档 9.3.2.3 ,
类似地, volatile语义(7.1.6.1)在访问对象及其非静态时应用于volatile成员函数 数据成员。
答案 2 :(得分:6)
以下代码:
#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
方法,我们可以假设,是的,x
和y
将为volatile
该方法,即使MyClass
的实例未声明为volatile
。
注意:如果您需要,可以使用volatile
删除const_cast<>
限定词;但要小心,因为就像const
这样做会在某些情况下导致未定义的行为。
答案 3 :(得分:1)
IBM implies它与const函数完全相同。
答案 4 :(得分: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
}
};