Last Updated:

Is the compiler allowed to permanently collapse a local variable?

void g();

void foo()
{
    volatile bool x = false;
    if (x)
        g();
}

You can see that neither nor optimize the potential call. In my understanding, this is correct: an abstract machine assumes that variables can change at any time (for example, due to hardware mapping), so constantly folding the initialization into validation would be incorrect.gccclanggvolatilefalseif

But MSVC completely eliminates access to (although read and write to are preserved!). Is this standard behavior?gvolatile


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.


Editing:

  • This discusses the deletion of reads and writes in : Is the compiler allowed to optimize a local variable? (thanks to Nathan!). I think the standard is quite clear that these reads and writes should happen. But this discussion does not cover the question of whether it is legitimate for the compiler to take the results of these readings for granted and optimize them on that basis. I'm guessing it's under-/not stated in the standard, but I'd be happy if someone proved me wrong.volatile

  • Of course, I can make a nonlocal variable to work around the problem. This question is more out of curiosity.x

4b9b3361

 

I think [intro.execution] (the paragraph number may vary) can be used to explain the behavior of the MSVC:

An instance of each object with an automatic retention duration is associated with each record in its block. Such an object exists and retains its last stored value during block execution and while the block is suspended...

The standard does not allow the exception of reading through a volatile value, but the paragraph above can be interpreted as allowing the value of .false


By the way, standard C (N1570 6.2.4/2) states that

The object exists, has a permanent address, and retains its last stored value for the duration of its lifetime. 34


34) In the case of a volatile object, the last store does not have to be explicit in the program.

It is unclear whether there can be implicit storage in an object with an automatic in-memory retention of the C/object model.