views:

242

answers:

4

Is there any reason that the compiler cannot optimize the following 2 statements out in main even I turned on fully optimization in Visual C++? Any side effect to access a int variable in memory?

int _tmain(int argc, _TCHAR* argv[])
{
    volatile int pleaseOptimizeMeOut = 100;

    (pleaseOptimizeMeOut);

    return 0;
}
+14  A: 

It can't optimise them out because you have declared the variable to be volatile. Loads and stores to volatile qualified objects are part of the "externally visible" effects of the C abstract machine.

(By the way, there are plenty of side effects when accessing a variable in memory; it can update hardware memory caches including the TLB, and possibly also cause page faults. And the memory your process is executing in might be being snooped on by another process, like a debugger).

caf
This effect is kind of the "point" of `volatile`.
TokenMacGuy
+5  A: 

On some computers, device I/O is modelled as memory read/writes. That's the kind of situation when volatile is properly used... it's telling the compiler explicitly not to assume that the variable operations aren't important or can be optimised....

Tony
+7  A: 

volatile explicitly tells the compiler not to optimize for that variable.

Steve Townsend
+3  A: 

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.

Eli Bendersky