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