Can compiler optimize comparing volatile variable to itself and assume it will be equal? Or it has to read twice this variable and compare the two values it got?
-
I would assume it would need to read twice because the very fact of volatility means that it can change between any two accesses. But I don't have any of the standards handy in a way that I could give an authoritative answer. – SoronelHaetir Nov 03 '21 at 06:31
-
@SoronelHaetir from the C perspective, a read could even alter the value. – Stefan Riedel Nov 03 '21 at 06:57
-
Strictly speaking, it depends on how the implementation defines what constitutes an access to a volatile object. But for "normal" implementations yes, the compiler needs to generate two reads and then compare. The value can change between the reads, or even *because* of the reads. – n. m. could be an AI Nov 03 '21 at 07:11
2 Answers
The way I think about volatile variables is that reading from them or writing to them is treated like an I/O function.
A call to an I/O function can never be optimized out, because it has side effects. Nor can a read or write involving a volatile variable be optimized out.
If you code two calls to the same input function, the compiler has to ensure the input function is actually called twice
, since it could give different results. In the same way, you can read from a volatile
variable twice, and in between the two reads, someone else could change the value of the variable. So the compiler will always emit the instructions to read it twice, whereas with non-volatile variables it can simply assume they're not modified by anyone outside the program.
Again, I/O functions calls can't be reordered, and nor can volatile variable accesses.

- 878
- 4
- 10
-
It is nice way to look on volatile which may answer lots of such question. Are we sure that all compilers supposed to act like this? Does it in some spec? – arye Nov 03 '21 at 11:05
-
-
Note that although the compiler generates two reads, the location will only be read twice if it is marked non-cacheable. How to do that is system-specific. – stark Nov 03 '21 at 11:42
-
thanks to correct me. but i know that Some compilers allow you to implicitly declare all variables as volatile. – vegan_meat Nov 03 '21 at 12:14
-
Unfortunately, while many commercial compilers intended for embedded programming will treat a `volatile` write as though it could trigger a call to a function about which the compiler can't expect to know anything (in part because on many embedded platforms it would not be uncommon for volatile writes to do things like trigger interrupts) there's no option I can find to make clang or gcc do likewise without disabling optimizations altogether. – supercat Mar 21 '22 at 20:31
C 2018 6.7.3 8 says:
An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to [an object with volatile-qualified type] shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3… What constitutes an access to an object that has volatile-qualified type is implementation-defined.
5.1.2.3 4 says:
… In the abstract machine, all expressions are evaluated as specified by the semantics…
In x == x
, where x
is a volatile-qualified object, the semantics are that the first x
is converted to the value of the object x
(by lvalue conversion per 6.3.2.1 2), the second x
is converted to its value, and the two values are compared. Converting an object to its value accesses the object, getting the value stored in it.
So the abstract machine accesses x
twice. By 6.7.3 8, this evaluation is strict; the actual program must implement the same accesses as the abstract machine, so the value of x
must be accessed twice; neither can be optimized away.
The C standard leaves it to the C implementation to define what constitutes an access. But whatever that is, the program must do it twice.

- 195,579
- 13
- 168
- 312