Originally Posted by
cyberfish
I have always understood volatile as meaning the variable can be changed outside of program flow (the links suggest that also).
In that case, the optimizer could argue that it can omit the read because the program doesn't care what value it has? since the result of the read is not assigned to anything, or used to make any decision.
Quite the opposite, actually. The volatile keyword tells the compiler that the variable may change as a result of something invisible to the compiler, and that the compiler needs to care about the changes that occur. If code has multiple reads, and the compiler can see nothing that changes the value, then "volatile" tells the compiler it cannot omit reads.
To answer the original question though, volatile (like const) is always an attribute of the thing immediately to its left in an expression, unless it is on the left, in which case it refers to the right.
So
Code:
volatile int *ptr = 0xsomeaddress;
guarantees that *ptr (if it is accessed) will always dereference 0xsomeaddress. It is equivalent to
Code:
int volatile *ptr = 0xsomeaddress;
If you care about ptr itself being changed by something invisible to the compiler, then you need to do
Code:
volatile int * volatile ptr = 0xsomeaddress;
(noting that the first usage of volatile can be either before or after the int keyword).