Pourquoi est-ce un point-à-volatile pointeur, comme “volatile int * p”, est-il utile?
volatile
est-à-dire au compilateur de ne pas optimiser la référence, de sorte que chaque lecture/écriture n'utilise pas la valeur stockée dans le registre mais un réel accès à la mémoire. Je peux comprendre que c'est utile pour certaines ordinaire variable, mais ne comprends pas comment volatile
affecte un pointeur.
volatile int *p = some_addr;
int a = *p; //CPU always has to load the address, then does a memory access anyway, right?
Quelle est la différence, si elle a été déclarée comme int *p = some_addr
?
Vous devez vous connecter pour publier un commentaire.
Un pointeur de la forme
est un pointeur vers une
int
que le compilateur va les traiter commevolatile
. Cela signifie que le compilateur suppose qu'il est possible pour la variablep
pointe à avoir changé, même si il n'y a rien dans le code source de suggérer que cela pourrait se produire. Par exemple, si j'ai misp
pour pointer vers un entier, alors chaque fois que je lis ou écris*p
le compilateur est conscient que la valeur peut avoir changé de façon inattendue.Il y a encore un cas d'utilisation pour un
volatile int*
: Si vous déclarez unint
commevolatile
, alors vous ne devriez pas point à la régulièreint*
. Par exemple, c'est une mauvaise idée:La raison pour cela est que le compilateur C ne se souvient plus que la variable pointée par
ptr
estvolatile
, de sorte qu'il peut mettre en cache la valeur de*p
dans un registre de façon incorrecte. En fait, en C++, le code ci-dessus est une erreur. Au lieu de cela, vous devez écrireMaintenant, le compilateur se souvient que
ptr
points à unvolatile int
, afin de ne pas (ou ne devrait pas!) essayer d'optimiser les accès par*ptr
.Un dernier détail - le pointeur que vous avez évoqué est un pointeur vers une
volatile int
. Vous pouvez également le faire:Ceci dit que le pointeur lui-même est
volatile
, ce qui signifie que le compilateur ne doit pas essayer de mettre en cache le pointeur dans la mémoire ou d'essayer d'optimiser la valeur du pointeur parce que le pointeur lui-même pourriez obtenir réaffecté par autre chose (matériel, etc.) Vous pouvez les combiner ensemble, si vous souhaitez obtenir cette bête:Ce dit que le pointeur et le pointee pourrait se changer de façon inattendue. Le compilateur ne peut pas optimiser le pointeur lui-même, et il ne peut pas optimiser ce qui est pointé.
Espérons que cette aide!
int
cours pointé n'est pas marquévolatile
, ce qui permettrait de compiler le code à l'identique avec et sansvolatile
.volatile
. Il serait très intelligent de compilateur pour ce faire, cependant. Ou suis-je incorrecte à ce sujet?do_something_else
est. Si le compilateur pourrait être tout à fait convaincu quedo_something_else
n'a jamais changé la valeur dex
, alors il pourrait très bien lire la valeur de*p
d'un registre si elle le voulait. Je doute que, pour tout être raisonnable code et la plupart des compilateurs que cela allait arriver, mais en théorie, il serait possible. Cela fait-il sens?volatile
à traiter et que le libellé de la norme est missleading. Heureusement, selon le rapport, pour la plupart, si pas tous les implémentations de le faire correctement et comme prévu.volatile
variera en fonction de la plate-forme cible et l'intention champ d'application. Sur de nombreuses plates-formes, d'avoir unvolatile
lire comporter avec acquérir de sémantique et d'un volatilewrite
se comporter avec la libération de la sémantique serait approprié. Sur certaines plates-formes où se lit peuvent déclencher des actions matérielles, ils devraient avoir communiqué ainsi que d'acquérir de la sémantique; de même, sur certaines plates-formes où l'écriture peut déclencher un décrochage jusqu'à ce qu'une opération d'e/S est terminée, ils devraient avoir à acquérir, mais aussi la libération de la sémantique.volatile
n'a pas besoin de faire quoi que ce soit pour des objets autres que automatique d'objets dans les fonctions qui utilisent dessetjmp
, et comptant comme un "effet secondaire" pour les fins de la prévention de la boucle élision. La Norme devrait donner des réalisateurs le pouvoir de décider ce qui est approprié, mais clair que la qualité des implémentations sera généralement faire plus que le minimum requis par la Norme [une note qui doit être appliquée dans de nombreux autres lieux].Ce code
volatile int *p = some_addr
déclare un pointeur vers unevolatile int
. Le pointeur lui-même n'est pasvolatile
.Dans le cas peu probable que vous avez besoin de le pointeur à être volatils ainsi que le type int, il vous faudra utiliser:
Je ne peux pas penser à une situation où vous auriez besoin de les utiliser.
Sur l'utilité de la volatilité:
Ceci est nécessaire, si vous avez besoin de vérifier la mémoire, qui est modifié par le matériel comme une série de contrôleur d'interface. Il a son application dans le monde des systèmes embarqués, où vous travaillez très proches du matériel sans OS dans l'entre-deux.