This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Spurious copies with user-defined conversions
- From: Matt Austern <austern at apple dot com>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 11 Nov 2002 15:50:53 -0800
- Subject: 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