Re: When may an [optimizing] C++ compiler omit object instantiations?
On Apr 21, 10:31 pm, blargg....@gishpuppy.com (blargg) wrote:
Victor Bazarov wrote:
John Lampe wrote:
[...]
int fooClass::barMethod(int i)
{
mutex_taker _mutex(g_mutex);
return i*2;
}
(Assuming the class 'mutex_taker' takes the mutex in its
constructor and releases it in its destructor).
What's preventing the compiler from optimizing the entire
construction of '_mutex' out? (disassembling a
functionally equivalent piece of real code shows the
expected; ctor and dtor of 'mutex_taker' are placed
inline).
[...]
*Temporary objects* are explicitly allowed to be optimized
away. Automatic objects are not.
Just to be more explicit, even temporary objects with clear
side-effects in their constructor/destructor, like printing to
cout, can be optimized.
To be more explicit (or more precise):
-- The rule doesn't concern temporaries, per se. What the
standard allows to be removed are *copies* of an object.
The exact rules concerning when are fairly complicated, but
the basic principle is that if you copy construct an object,
then immediately destruct the copied object, the compiler is
allowed to "merge" the two objects, suppressing both the
copy construction and the destruction, even if one or the
other have observable side effects.
(Note that if I write a statement something like:
ScopedMutex( m ), i = 2*i ;
, the ScopedMutex is a temporary. The compiler is still not
allowed to optimize it away. On the other hand, in the case
of NRVO, the compiler is expressedly allowed to "merge" two
different non-temporary values.)
-- Except for such special rules (and I can't think of another
one off hand), the compiler is not allowed to optimize
anything that affects the observable behavior of the
program. The standard even has specific language for this
case: "If a named automatic object has initialization or a
destructor with side effects, it shall not be destroyed
before the end of its block, nor shall it be eliminated as
an optimization even if it appears to be unused, except that
a class object or its copy may be eliminated as specified in
12.8." (=A712.8 is where the rule concerning the suppression
of copies is elaborated.)
This text is really redundant, of course, since the basic
rule concerning conformance is that the standard describes
the behavior of an abstract machine, without optimization,
and then allows an implementation to do anything, provided
it doesn't change the observable behavior. In this case,
the abstract machine does construct the object, and
destructs it when it goes out of scope; if the compiler can
determine that not doing so has no impact on the observable
behavior of the program, it is free to do so, but only if it
can determine that there is no impact on the observable
behavior of the program.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34