web-dev-qa-db-ja.com

C ++揮発性メンバー関数

class MyClass
{
    int x, y;
    void foo() volatile {
        // do stuff with x
        // do stuff with y
    }   
};

xおよびyvolatileとして宣言する必要がありますか、それともすべてのメンバー変数が自動的にvolatileとして扱われますか?

コンパイラーが "xを含むもの"を "yを含むもの"に並べ替えないようにします。

編集:通常の型をvolatile型にキャストするとどうなりますか?これは、その場所へのアクセスを並べ替えないようにコンパイラーに指示しますか?特殊な状況で通常の変数を、パラメーターが揮発性である関数に渡したいのですが。コンパイラがその呼び出しを前または後の読み取りと書き込みで並べ替えないようにする必要があります。

41
0xbadf00d

メンバー関数をvolatileとマークすることは、constとマークするようなものです。これは、レシーバーオブジェクトがvolatile T*として宣言されているかのように扱われることを意味します。その結果、xまたはyへの参照はすべて、メンバー関数でvolatile読み取りとして扱われます。さらに、volatileオブジェクトはvolatileメンバー関数のみを呼び出すことができます。

とにかく、本当にそれらへのすべてのアクセスをxとして扱いたい場合は、とにかくyおよびvolatilevolatileをマークすることができます。

36
templatetypedef

しないでくださいメンバー変数を明示的に宣言する必要があります。

標準ドキュメント9.3.2.3から、

同様に、揮発性セマンティクス(7.1.6.1)オブジェクトとその非静的データメンバーにアクセスするときに揮発性メンバー関数に適用します。

10
liaK

次のコード:

#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およびyvolatileになると想定できます。メソッドでは、たとえMyClassのインスタンスがvolatileとして宣言されていなくても。

注:必要に応じて、const_cast<>を使用してvolatile修飾子を削除できます。ただし、constと同様に、場合によっては未定義の動作が発生する可能性があるので注意してください。

8
ereOn

IBMの意味 const関数とまったく同じように機能します。

1
Flexo

したがって、元の例を使用します。

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