C++结构体/类中的非静态成员变量是否需要标记为volatile才能在成员函数中被视为volatile?

bis0qfac  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(130)
class MyClass
{
    int x, y;
    void foo() volatile {
        // do stuff with x
        // do stuff with y
    }   
};

是否需要将xy声明为volatile,或者将所有成员变量自动视为volatile
我想确保编译器不会将“stuff with x“与“stuff with y“重新排序。
编辑:如果我将普通类型转换为volatile类型会发生什么?这是否会指示编译器不重新排序对该位置的访问?我想在一个特殊的情况下传递一个普通的变量给一个参数是volatile的函数。我必须确保编译器不会将该调用与之前或之后的读取和写入重新排序。

6pp0gazn

6pp0gazn1#

将成员函数标记为volatile就像将其标记为const;这意味着接收器对象被视为好像它被声明为volatile T*。因此,任何对xy的引用都将被视为成员函数中的volatile读取。此外,volatile对象只能调用volatile成员函数。
也就是说,如果您确实希望将对xy的所有访问都视为volatile,则无论如何都可能希望将它们标记为volatile

guykilcj

guykilcj2#

必须显式声明成员变量。
来自标准文档 9.3.2.3
同样,volatile语义(7.1.6.1)在访问对象及其非静态数据成员时适用于volatile成员函数。

hyrbngr7

hyrbngr73#

下面的代码:

#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方法,所以我们可以假设,是的,xy在方法中将是volatile,即使MyClass的示例没有声明为volatile
注意:如果需要,可以使用const_cast<>删除volatile限定符;但是要小心,因为就像const一样,在某些情况下这样做会导致未定义的行为。

xriantvc

xriantvc4#

因此,使用原始示例:

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

相关问题