Re: [ROOT] Seg.Violation on return TGraph

From: Rene Brun (Rene.Brun@cern.ch)
Date: Thu Mar 13 2003 - 10:03:46 MET


Hi Christian,

Let me retract part of what I said about illegal C++. I should have said
"dangerous and inefficient C++"

I have my personal view on your RVO, NRVO and other UFOs that you quote
in your mail. I must say that I have a "const" attitude wrt to some
"volatile" concepts. My CV is "cv-qualified" type and I hope that it will not 
be disqualified by the upcoming "move-semantic" of ISO/IEC C++ standard ::)

The point in my mail was to discourage the use of a return by value
for objects that can be pretty large. I have a remark about copy constructors in
general. It is often unclear what a copy constructor should do.
Some complex objects like TGraph, TH1, TTree, have collections
of other objects or references. These objects may be named objects
in some directory, Hashtable or like. A copy (in the C++ sense) may have
many side-effects if one is not careful. This is the reason why we
implemented the Clone function that makes a deep copy of the object itself
including its dependencies and give the possibility to give a name
to the new cloned object in one single operation.

I have a remark on the "smart" code that you send in your mail. As already
pointed out by Nick, this code is not portable. I don't think that one
should encourage users to systematically move to the latest "modern" way
when simpler and more efficient solutions are around.

Rene Brun

etc Christian Holm Christensen wrote:
> 
> Hello again,
> 
> Christian Holm Christensen <cholm@hehi03.nbi.dk> wrote concerning
>   Re: [ROOT] Seg.Violation on return TGraph [Wed, 12 Mar 2003 22:06:21 +0100 (CET)]
> ----------------------------------------------------------------------
> > Hi Rene,
> >
> >
> > Rene Brun <Rene.Brun@cern.ch> wrote concerning
> >   Re: [ROOT] Seg.Violation on return TGraph [Wed, 12 Mar 2003 19:57:35 +0100 (MET)]
> > ----------------------------------------------------------------------
> >
> >   foo create_foo4(int x) {
> >     std::cout << "+ 4: direct object" << std::endl;
> >     return foo(x);
> >   }
> >
> ...
> >
> > In particular notice the 3rd case, were the function construct the
> > object on the return stack, rather than as a temporary.  I haven't
> > checked with the ISO/IEC standard whether this the correct _and_
> > guarantied behaviour, but it compiles and works the same with both GCC
> > 3.0.4, Intel's C++ compiler version 7.0, Compaq C++ v6.3, and Sun
> > WorkShop 4.2 so I'd say there's a pretty good chance it's right.  Now,
> > whether other compilers (and linkers) behave the same - I really have
> > no idea (my guess is at least one will behave differently, even if the
> > behaviour is dictated by the ISO/IEC standard - guess which one :-)
> 
> OK. I looked it up.  The relevant section is 12.8, paragraph 15, which
> reads:
> 
>   Whenever a temporary class object is copied using a copy
>   constructor, and this object and the copy have the same
>   cv-unqualified type, an implementation is permitted to treat the
>   original and the copy as two different ways of referring to the same
>   object, and not perform a copy at all, even if the class copy
>   constructor or destructor have side effects.  For a function with a
>   class return type, if the expression in the return statement is the
>   name of a local object, and the cv-unqualified type of the local
>   object is the same as the function return type, an implementation is
>   permitted to omit creating the temporary object to hold the function
>   return value, even if the class constructor or destructor has side
>   effects. In these cases, the object is destroyed at the later of
>   times when the original and the copy would have been destroyed
>   without the optimization. [Example
> 
>     class Thing {
>     public:
>             Thing();
>             ~Thing();
>             Thing(const Thing&);
>             Thing operator=(const Thing&);
>             void fun();
>     };
> 
>     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.]
> 
> [For those who don't know, `cv-unqualified type' means that the type
> has neither a `const' nor a `volatile' qualifier].
> 
> So, in essence, the behaviour I stipulated in the previous email,
> regarding the 4th scenario (and not the 3rd as I wrote before) is
> optional.  However, It would be a stupid compiler writer that didn't
> follow this behaviour, as it'll tend to make the compiled code a lot
> faster.
> 
> Also, please read Andrei Alexandrescu thoughts on RVO and NRVO in the
> previously cited article from C/C++ journal. His idea is that you
> should use smart pointers.  In fact, one could argue that ROOT should
> use smart pointers a whole lot more than what is presently the case.
> A good place to start would be to automatically create a dictionary
> for `std::auto_ptr<Class>' for each `Class' one creates a dictionary
> for.  Note, that there's a proposal for `move-semantics' for the
> upcoming ISO/IEC C++ standard (version 2) [1]
> 
> 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
>  | |
> 
> [1] http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm



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