Подтвердить что ты не робот

Функции нестабильных членов С++

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 5

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

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