Pourquoi un pointeur pointu vers volatile, comme "volatile int * p", est-il utile?
volatile
est de 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 fait un accès mémoire réel. Je peux comprendre qu'il soit utile pour certaines variables ordinaires, mais je 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
?
2 réponses
un pointeur de la forme
volatile int* p;
est un pointeur vers un int
que le compilateur traitera comme volatile
. Cela signifie que le compilateur supposera qu'il est possible que la variable que p
pointe ait changé même si rien dans le code source ne suggère que cela pourrait se produire. Par exemple, si je mets p
pour pointer vers un entier régulier, 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 un cas d'utilisation supplémentaire pour un volatile int*
: si vous déclarez un int
comme volatile
, alors vous ne devriez pas le pointer avec un int*
régulier . Par exemple, c'est une mauvaise idée:
volatile int myVolatileInt;
int* ptr = &myVolatileInt; // Bad idea!
la raison en est que le compilateur C ne se souvient plus que la variable pointée par ptr
est volatile
, donc il pourrait cacher la valeur de *p
dans un inscription incorrecte. En fait, en C++, le code ci-dessus est une erreur. Au lieu de cela, vous devriez écrire
volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt; // Much better!
maintenant, le compilateur se souvient que ptr
pointe à un volatile int
, donc il ne va pas (ou ne devrait pas!) essayez d'optimiser les accès par *ptr
.
un dernier détail - le pointeur dont vous avez parlé est un pointeur vers un volatile int
. Vous pouvez aussi faire ceci:
int* volatile ptr;
cela dit que le pointeur lui-même est volatile
, ce qui signifie que le compilateur ne devrait pas essayer de mettre en cache le pointeur dans la mémoire ou essayer d'optimiser la valeur du pointeur parce que le pointeur lui-même pourrait être réassigné par quelque chose d'autre (matériel, etc.) Vous pouvez les combiner si vous voulez obtenir cette bête:
volatile int* volatile ptr;
cela signifie que le pointeur et le pointé peuvent être changés 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!
ce code volatile int *p = some_addr
déclare un pointeur vers un volatile int
. Le pointeur lui-même n'est pas volatile
.
dans le cas peu probable que vous aviez besoin du pointeur pour être volatile aussi bien que l'int, vous auriez besoin d'utiliser:
volatile int * volatile p;
Je ne peux pas penser à une situation où vous auriez besoin d'utiliser cela.