Question

I understand when you need a pointer to a volatile value (e.g. doing a read of a memory mapped peripheral). But when would you need the pointer itself to be volatile?>

Was it helpful?

Solution

To elaborate on my comment a little bit, it's important to first keep in mind what volatile means: it's a signal to the compiler that the variable being declared can change in unexpected ways through mechanisms that the compiler cannot see or control and that reads and writes may have side-effects. As a result, a compiler will typically reload the value of the variable every time from main memory instead of using a cached value and will not perform optimizations that remove, reorder or elide reads or writes to such volatile variables.

Typically this sort of thing is something that most userspace code doesn't have to worry about and legitimate uses of volatile from there are few and far between.

Your question also references a subtle and not well-known feature of the language: the ability to declare a pointer itself as volatile (or const) instead of thing that it points to. You do this with this syntax:

int *volatile p = 0x74;

This declares a volatile pointer that points to an int at memory location 0x74. Contrast this with:

volatile int *p = 0x74;

which declares a pointer to a volatile int at address 0x74

The difference between this two is what happens when you access p. We'll only concern ourselves with the read case:

In the case of the pointer to volatile int for every read access the compiler will go to memory location 0x74 and read (perhaps using special CPU instructions) the int value at that location - the value will not be cached by the code (but it might be by the hardware).

In the case of the volatile pointer to int the compiler will reload the value of the pointer at every access and then go and read the int at that address. The address will not be cached in the code (but again, it may be cached by the hardware).

And similarly with writes.

Again, be sure to remember that volatile restricts the compiler (e.g. it can't optimize away a write or a read) since any operation on the volatile variable might have side-effects that are not visible to the compiler. An example of such a side effect might be generating an interrupt, blinking an LED, writing an audit record or changing the value of a register.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top