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