Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a C++ Compiler Eliminate a Volatile Local Var that is not Read

Say, I have this code:

int f() {
  volatile int c;
  c=34;
  return abc();
}

The volatile int c is never read. But it is marked as volatile, can the compiler eliminate it altogether? My testing in Visual C++ 2010 shows contradictory results. In VC++, if I enable optimization (maximizing speed) the above function contains a local variable called c (by looking at the generated assembly listing). But, instead of using assignment operator, I also tried to initialize the variable by a compiler intrinsic function like memset() (and enable using compiler intrinsic functions), the variable is eliminated.

int f() {
  volatile int c;
  memset((void*)&c,34, 1); 
  return abc();
}

So according to the C++ standard, can compiler eliminate the volatile int c? I'm thinking probably there is some inconsistent behaviour in VC++ related to how intrinsic functions optimize volatile variable.

like image 488
JavaMan Avatar asked Dec 21 '22 05:12

JavaMan


2 Answers

memset((void*)&c,34, 1); has undefined behaviour (§7.1.6.1/6). The compiler is therefore allowed to produce any result.

If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with a non-volatile-qualified type, the program behavior is undefined.

Please, do not use casts like that, much less C-style casts. When one does not know what the correct C++ cast is for a certain situation, it is likely a situation where one should not be casting anything.

like image 110
R. Martinho Fernandes Avatar answered Dec 24 '22 00:12

R. Martinho Fernandes


So according to the C++ standard, can compiler eliminates the volatile int c?

No. volatile-qualified objects are used for reading from or writing to the hardware, and the side-effects of assigning a volatile object are observable.

Therefore, in compliance with the constraints on optimizations placed by the so-called "as-if" rule, conforming implementations are not allowed to optimize away c. The "as-if" rule is formally introduced in Paragraph 1.9/1 of the C++11 Standard:

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below

And the concept of "observable behavior" is defined in paragraph 1.9/8:

The least requirements on a conforming implementation are:

Access to volatile objects are evaluated strictly according to the rules of the abstract machine.

— At program termination, all data written into files shall be identical to one of the possible results that execution of the program according to the abstract semantics would have produced.

— The input and output dynamics of interactive devices shall take place in such a fashion that prompting output is actually delivered before a program waits for input. What constitutes an interactive device is implementation-defined.

These collectively are referred to as the observable behavior of the program. [...]

Since access to volatile objects must be evaluated strictly according to the rules of the abstract machine, compilers are not allowed to optimize away c and the corresponding assignment operation.

like image 32
Andy Prowl Avatar answered Dec 24 '22 02:12

Andy Prowl