Other answers stressed the importance of volatile
here, and I have nothing to add to that. However, I want to say how important it is that such a construct exists, because it is useful. From my hardware design experience, many times the interface between a CPU and a logic block in HW is based on memory writes and reads. This means that when a CPU reads some register from the HW, something happens (i.e. interrupt clears, queue advances, and many other options).
Now, once you execute the access to pleaseOptimizeMeOut
, since it's volatile
the compiler just assumes you might have done it just for the side effect, so it would be absolutely wrong to optimize it. Suppose the variable is mapped to a HW queue and you just wanted to advance the queue without actually taking a value from it.
That said, mapping variables to registers when reading has side effects is IMHO not a good practice, and it would be better to encapsulate it with a function call, exactly for the reason your question demonstrates - it's confusing in some cases.
Mapping variables to registers without side effects is very useful and widely used, however.