From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17962 invoked by alias); 13 Feb 2004 14:08:36 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 17955 invoked by uid 48); 13 Feb 2004 14:08:34 -0000 Date: Fri, 13 Feb 2004 14:08:00 -0000 From: "christian dot engstrom at glindra dot org" To: gcc-bugs@gcc.gnu.org Message-ID: <20040213140825.14140.christian.engstrom@glindra.org> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug c++/14140] New: Unwanted call to derived constructor after implicit conversion X-Bugzilla-Reason: CC X-SW-Source: 2004-02/txt/msg01400.txt.bz2 List-Id: I posted essentially the following to comp.lang.c++, where it was suggested that I report this as a possible gcc bug: -------- When i compile the program listed below with gcc version 3.3.1 (MinGW on Windows XP) I get the following result: Calling 'func(d)': 'base' copy constructor Calling 'func(*d_handle)': 'base' copy constructor Calling 'func(d_handle)': 'derived' copy constructor <-- Why? 'base' copy constructor The problem is the call to the 'derived' copy constructor, which I don't want and hadn't expected, and which Microsoft Visual C++ 6.0 doesn't generate. Is it the gcc or the MSVC compiler that is broken? I would naively have assumed that MSVC is right and gcc is wrong in this case, but perhaps there is something in the standard that prescribes the gcc behavior for some reason? My intention was that there shouldn't be any temporary 'derived' objects created at all, since both the implicit conversion operator from 'derived_handle' to 'derived' and 'derived's operator* return references to an existing 'derived' object. ------------ In the comp.lang.c++ newsgroup lilburne wrote: > > It looks like a gcc bug. The compiler is treating the returned derived& > differently when it is returned from the conversion function > > operator derived&() > > to what it does when it calls dereference function: > > derived& operator*() > > even if operator derived&() is rewritten in the clearer form > > operator derived&() const {return operator*();} > > the extra constructor is called. > -------------- The output from the command gcc -v looks like this: Reading specs from c:/app/mingw/bin/../lib/gcc-lib/mingw32/3.3.1/specs Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c,c++,f77,objc,ada,java --disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchronization Thread model: win32 gcc version 3.3.1 (mingw special 20030804-1) ------------- The program that causes the problem: ======================================================================= #include //---------------------------------------------------------------------------- class base { public: base() {} base(const base&) {std::cout << " 'base' copy constructor" << std::endl;} }; //---------------------------------------------------------------------------- class derived : public base { public: derived() {} derived(const derived&) {std::cout << " 'derived' copy constructor" << std::endl;} }; //---------------------------------------------------------------------------- class derived_handle { derived* tptr; public: derived_handle() {}; derived_handle(derived* inptr) : tptr(inptr) {} derived& operator*() const {return *tptr;} derived* operator->() const {return tptr;} operator derived&() const {return **this;} // Implicit conversion to 'derived' }; //---------------------------------------------------------------------------- void func(base b) {} // Takes the parameter by value //============================================================================ int main (int argc, char* argv[]) { derived d; derived_handle d_handle(new derived()); std::cout << "\nCalling 'func(d)':" << std::endl; func(d); std::cout << "\nCalling 'func(*d_handle)':" << std::endl; func(*d_handle); std::cout << "\nCalling 'func(d_handle)':" << std::endl; func(d_handle); // Calls 'derived' copy constructor with gcc (only) return 0; } -- Summary: Unwanted call to derived constructor after implicit conversion Product: gcc Version: 3.3.1 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: christian dot engstrom at glindra dot org CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14140