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