web-dev-qa-db-fra.com

Fonctions de membre volatile C ++

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

Dois-je déclarer x et y comme volatile ou toutes les variables de membre traitées comme volatile automatiquement?

Je veux m'assurer que "des choses avec x" ne sont pas réorganisées avec "trucs avec y" par le compilateur.

EDIT: Que se passe-t-il si je jette un type normal sur un type volatile? Cela demanderait-il que le compilateur ne réalise pas l'accès à cet emplacement? Je veux transmettre une variable normale dans une situation particulière à une fonction quel paramètre est volatile. Je dois être sûr que le compilateur ne réoriente pas cet appel avec des lectures antérieures ou suivies.

41
0xbadf00d

Marquage d'une fonction de membre volatile est comme le marquant const; Cela signifie que l'objet du récepteur est traité comme s'il était déclaré comme un volatile T*. En conséquence, toute référence à x ou y sera traité comme un volatile lecture dans la fonction membre. De plus, un objet volatile ne peut que appeler volatile fonctions membres.

Cela dit, vous voudrez peut-être marquer x et yvolatile de toute façon si vous voulez vraiment que tous les accès à eux soient traités comme volatile.

36
templatetypedef

Vous ne doit déclarer explicitement les variables de membre ..

Des documents standard 9.3.2.3 ,

De même, Semantiques volatiles (7.1.6.1) Appliquer dans les fonctions de l'élément volatile lors de l'accès à l'objet et à ses membres de données non statiques.

10
liaK

Le code suivant:

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

Soulève une erreur lors de la compilation avec 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>

Et puisque a volatile instance ne peut pas appeler un non-volatile méthode, nous pouvons supposer que, oui, x et y _ sera volatile dans la méthode, même si l'instance de MyClass n'est pas déclarée volatile.

Remarque: vous pouvez supprimer le qualificatif volatile à l'aide d'un const_cast<> Si vous avez besoin de; Cependant, soyez prudent parce que comme const cela peut conduire à un comportement indéfini dans certains cas.

8
ereOn

IBM implique Cela fonctionne exactement comme des fonctions de const.

1
Flexo

Ainsi, en utilisant l'exemple original:

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