С ++ изменчивые функции-члены - PullRequest
36 голосов
/ 28 января 2011
class MyClass
{
    int x, y;
    void foo() volatile {
        // do stuff with x
        // do stuff with y
    }   
};

Нужно ли объявлять x и y как volatile или все переменные-члены будут обрабатываться как volatile автоматически?

Я хочу убедиться, что "заполнитьx "не переупорядочивается компилятором с" stuff with y ".

EDIT: Что произойдет, если я приведу обычный тип к типу volatile?Будет ли это указывать компилятору не изменять порядок доступа к этому расположению?Я хочу передать нормальную переменную в особой ситуации функции, параметр которой является переменным.Я должен быть уверен, что компилятор не переупорядочивает этот вызов с предыдущим или последующим чтением и записью.

Ответы [ 5 ]

31 голосов
/ 28 января 2011

Маркировка функции-члена volatile похожа на маркировку const; это означает, что объект-получатель обрабатывается так, как если бы он был объявлен как volatile T*. Следовательно, любая ссылка на x или y будет рассматриваться как volatile, считанная в функции-члене. Более того, объект volatile может вызывать только volatile функции-члены.

Тем не менее, вы можете пометить x и y volatile в любом случае, если вы действительно хотите, чтобы все обращения к ним рассматривались как volatile.

8 голосов
/ 28 января 2011

Вы не должны явно объявить переменные-члены ..

Из стандартных документов 9.3.2.3 ,

Точно так же изменчивая семантика (7.1.6.1) применяется в функциях изменяемых элементов при доступе к объекту и его нестатическим элементам данных.

6 голосов
/ 28 января 2011

следующий код:

#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, в некоторых случаях это может привести к неопределенному поведению.

1 голос
/ 04 сентября 2014

Итак, используя оригинальный пример:

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 голос
/ 28 января 2011

IBM подразумевает , что работает точно так же, как и константные функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...