Spurious copies with user-defined conversions

Matt Austern austern@apple.com
Mon Nov 11 17:04:00 GMT 2002


Consider this program:
     #include <stdio.h>

     struct Base {
       Base() { printf("Default constructing at %p\n", this); }
       Base(const Base &b) { printf("Copying %p to %p\n", &b, this); }
     };

     struct Derived : public Base { };

     struct Wrapper {
       operator Derived & () {
         printf("Yielding myDerived@%p\n", &myDerived);
         return myDerived;
       }
       Derived myDerived;
     };

     void foo(const Base &x)
     { printf("Arg of foo at %p\n", &x); }

     int main()
     {
       Wrapper x;
       foo((Base &) x);
     }

When I compile and run it with gcc 2.95, I get:
     bash-2.05$ g++ a.cc ; ./a.out
     Default constructing at 0xbffff900
     Yielding myDerived@0xbffff900
     Arg of foo at 0xbffff900

When I compile and run it with 3.3, however, I get:
     bash-2.05$ ~/root/bin/g++ a.cc ; ./a.out
     Default constructing at 0xbffff400
     Yielding myDerived@0xbffff400
     Copying 0xbffff400 to 0xbffff3f0
     Arg of foo at 0xbffff3f0

(FWIW, 3.0.2, 3.1, and 3.2 all have the same behavior.)

Always possible that I'm wrong, but it looks to me like gcc 2.95 is
right, and that this is a regression.  Seems to me we should be
applying the user-defined operator Derived& operator, then we
should be applying the standard derived-to-base conversion,
then we should be applying the standard nonconst-reference-to-
const-reference conversion.  None of those should involve any
copies.  I can't see any good reason for the compiler to invoke
the copy constructor here.

Anyone want to construct an argument that the gcc 3.x behavior
is correct?

			--Matt



More information about the Gcc mailing list