This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Spurious copies with user-defined conversions


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]