ISO/IEC Copy CTOR and (N)RVO [was: Re: [ROOT] Seg.Violation on return TGraph]

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Thu Mar 13 2003 - 13:54:52 MET


Hi Nick, 

Nick West <n.west1@physics.ox.ac.uk> wrote concerning
  RE: [ROOT] Seg.Violation on return TGraph [Thu, 13 Mar 2003 07:55:40 -0000] 
----------------------------------------------------------------------
> Hi Christian,
> 
> thanks for your interesting and enlightening emails; I always look forward
> to them.  Just in case anyone else tries your example on more recent gcc
> compilers, I will report that, under gcc 3.2 I get, for the first case:-
> 
> + 1: plain object
> - 1: foo::foo(int)
> ==> Notice the extra copy above?

Ah, so GCC 3.2 does Named Return Value Optimisation (NRVO), while ... 

> and only when I went back to 2.91, do I get:-
> 
> + 1: plain object
> - 1: foo::foo(int)
> - 1: foo::foo(const foo&)
> - 1: foo::~foo
> ==> Notice the extra copy above?

... GCC 2.91 (and GCC 3.0, and GCC 2.95) does only Return Value
Optimisation (RVO).

> So, as your second mail explained:-
> 
> >    Thing f() { 
> >            Thing t;
> >	    return t;
> >    }
> >    
> >    Thing t2 = f();
> >
> >  Here t does not need to be copied when returning from f. The return
> >  value of f may be constructed directly into the object t2.]
> 
> So the casual programmer now goes unpunished for the profligate use of
> temporary objects with gcc.  Of course it's good that the compiler writer
> seeks to optimise the compiled code but there is the danger that the
> programmer will become sloppy member of the partnership.  

There's always that danger when a programmer relies on optional
features of a language.  Remember, GCC 3.2 is correct in doing the
NRVO (or just RVO), as the ISO/IEC standard allows it.  Other
compilers would be right too if they didn't do (N)RVO, the standard
allows that too.   The point is, that to code really portable C++, you
have to know a bit about the ISO/IEC standard (at least have a copy in
your bookshelves :-) That may indeed discourage some, especially as
the ISO/IEC C++ standard is a 800+ pages document in not-too-clear
language.  Hopefully the next version will be a lot better (maybe
include an overview of optional features?). 

Note the option `-fno-elide-constructors' to GCC:

  `-fno-elide-constructors'
       The C++ standard allows an implementation to omit creating a
       temporary which is only used to initialize another object of the
       same type.  Specifying this option disables that optimization, and
       forces g++ to call the copy constructor in all cases.

For development purposes it might be a good idea to pass that  option
to GCC, so that one is sure that the code behaves well, even if a
compiler does not support the (N)RVO. 

> What if several local objects are created and then one chosen for
> return?  Clever compilers cannot help then.

There's some stuff in the ISO/IEC standard on that.  It's pretty long,
and I haven't read it - look in chapter 12 which deals with these kind
of things, 

Yours, 

 ___  |  Christian Holm Christensen 
  |_| |	 -------------------------------------------------------------
    | |	 Address: Sankt Hansgade 23, 1. th.  Phone:  (+45) 35 35 96 91
     _|	          DK-2200 Copenhagen N       Cell:   (+45) 24 61 85 91
    _|	          Denmark                    Office: (+45) 353  25 305
 ____|	 Email:   cholm@nbi.dk               Web:    www.nbi.dk/~cholm
 | |



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:10 MET