class MyClass
{
int x, y;
void foo() volatile {
// do stuff with x
// do stuff with y
}
};
x
およびy
をvolatile
として宣言する必要がありますか、それともすべてのメンバー変数が自動的にvolatile
として扱われますか?
コンパイラーが "x
を含むもの"を "y
を含むもの"に並べ替えないようにします。
編集:通常の型をvolatile
型にキャストするとどうなりますか?これは、その場所へのアクセスを並べ替えないようにコンパイラーに指示しますか?特殊な状況で通常の変数を、パラメーターが揮発性である関数に渡したいのですが。コンパイラがその呼び出しを前または後の読み取りと書き込みで並べ替えないようにする必要があります。
メンバー関数をvolatile
とマークすることは、const
とマークするようなものです。これは、レシーバーオブジェクトがvolatile T*
として宣言されているかのように扱われることを意味します。その結果、x
またはy
への参照はすべて、メンバー関数でvolatile
読み取りとして扱われます。さらに、volatile
オブジェクトはvolatile
メンバー関数のみを呼び出すことができます。
とにかく、本当にそれらへのすべてのアクセスをx
として扱いたい場合は、とにかくy
およびvolatile
volatile
をマークすることができます。
しないでくださいメンバー変数を明示的に宣言する必要があります。
標準ドキュメント9.3.2.3から、
同様に、揮発性セマンティクス(7.1.6.1)オブジェクトとその非静的データメンバーにアクセスするときに揮発性メンバー関数に適用します。
次のコード:
#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
として宣言されていなくても。
注:必要に応じて、const_cast<>
を使用してvolatile
修飾子を削除できます。ただし、const
と同様に、場合によっては未定義の動作が発生する可能性があるので注意してください。
IBMの意味 const関数とまったく同じように機能します。
したがって、元の例を使用します。
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
}
};