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 ?

65
demandé sur templatetypedef 2012-03-30 03:43:27

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!

113
répondu templatetypedef 2018-05-25 02:10:48

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.

8
répondu markgz 2012-03-29 23:58:28