Consider this simple code:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
You can see that neither gcc
nor clang
optimize out the potential call to g
. This is correct in my understanding: The abstract machine is to assume that volatile
variables may change at any moment (due to being e.g. hardware-mapped), so constant-folding the false
initialization into the if
check would be wrong.
But MSVC eliminates the call to g
entirely (keeping the reads and writes to the volatile
though!). Is this standard-compliant behavior?
Background: I occasionally use this kind of construct to be able to turn on/off debugging output on-the-fly: The compiler has to always read the value from memory, so changing that variable/memory during debugging should modify the control flow accordingly. The MSVC output does re-read the value but ignores it (presumably due to constant folding and/or dead code elimination), which of course defeats my intentions here.
Edits:
The elimination of the reads and writes to
volatile
is discussed here: Is it allowed for a compiler to optimize away a local volatile variable? (thanks Nathan!). I think the standard is abundantly clear that those reads and writes must happen. But that discussion does not cover whether it is legal for the compiler to take the results of those reads for granted and optimize based on that. I suppose this is under-/unspecified in the standard, but I'd be happy if someone proved me wrong.I can of course make
x
a non-local variable to side-step the issue. This question is more out of curiosity.