C des fonctions membres volatils
-
26-10-2019 - |
Question
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 seront toutes les variables membres traités comme volatile
automatiquement?
Je veux faire en sorte que « des choses avec x
» n'est pas réorganisés avec « trucs avec y
» par le compilateur.
EDIT:
Que faire si je suis en jetant un type normal à un type de volatile
? Serait-ce demander au compilateur d'accéder non Réorganiser à cet endroit? Je veux passer une variable normale dans une situation particulière à une fonction qui paramètre est volatile. Je dois être sûr compilateur ne Réorganiser cet appel avec avant ou suivi de lecture et d'écriture.
La solution
Marquage d'une fonction membre volatile
est comme marquant const
; cela signifie que l'objet récepteur est traitée comme si elle avait été déclarée comme volatile T*
. Par voie de conséquence, toute référence à x
ou y
sera traité comme un volatile
lu dans la fonction de membre. De plus, un objet volatile
ne peut appeler des fonctions membres de volatile
.
Cela dit, vous pouvez marquer x
et y
volatile
de toute façon si vous voulez vraiment tous les accès à eux être traités comme volatile
.
Autres conseils
ne pas doivent déclarer les variables membres explicitement ..
De docs standard 9.3.2.3 ,
De même, sémantique volatiles (7.1.6.1) appliquer des fonctions membres volatils lors de l'accès de l'objet et sa non statique membres de données.
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;
}
génère 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 comme une instance de volatile
ne peut pas appeler une méthode non-volatile
, on peut 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 de volatile
en utilisant un const_cast<>
si jamais vous devez; Attention cependant, car tout comme const
cela peut conduire à un comportement non défini dans certains cas.
IBM implique cela fonctionne exactement comme les fonctions const.
Donc, en utilisant l'exemple d'origine:
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
}
};