This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
g++: incorrect implicit copy constructor
- To: gcc-bugs at gcc dot gnu dot org
- Subject: g++: incorrect implicit copy constructor
- From: "Kanze, James" <James dot Kanze at Dresdner-Bank dot com>
- Date: Tue, 20 Feb 2001 13:29:44 +0100
I've found an error in the implicitly defined copy constructor in g++,
version 2.95.2, under Windows NT. Consider the following code:
----------------example program-----------------
#include <iostream.h>
#include <typeinfo>
struct B {
B() { }
B( B const& other ) { cout << "B copy\n" ; }
template< typename D >
B( D const& other ) { cout << "B template (" << typeid( D ).name() <<
")\n" ; }
} ;
struct D : B {
} ;
int
main()
{
D d1 ;
D d2( d1 ) ;
return 0 ;
}
----------------example program-----------------
When run, this program outputs:
B template (1D)
According to the standard, it should output:
B copy
The template constructor, instantiated for D, is being used instead of
the copy constructor.
In this case, the compiler is generating the implicit copy constructor
for D incorrectly. According to 12.8/8 of the standard, "The
implicitly-defined copy constructor for class X performs a member-wise
copy of its sub-objects [...] if the subobject is of class type, the
copy constructor for the class is used." 12.8/2 makes it clear that a
template constructor is never a copy constructor -- in this case, the
generated constructor would not even be a copy constructor if it were
not a template, since the parameter is not a reference to B.
A quick check shows that the same problem occurs if B has a
constructor taking a D const&, rather than a template; in practice,
this is rather rare, however, where as the template case is more
likely. (I stumbled on it when working on a response to a problem in
comp.lang.c++.moderated.)
The only work-around I've found is to explicitly provide the copy
constructor, with a static_cast of the reference argument to the base
class type, e.g.:
D::D( D const& other )
: B( static_cast< B const& >( other ) )
{
}
-----------------output of g++ -v pbcctor.cc -o pbcctor --------------
Reading specs from
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/specs
gcc version 2.95.2 19991024 (release)
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/cpp.exe -lang-c++ -v -iprefix
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/ -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -Di386
-D_WIN32 -DWINNT -D_X86_=1 -D__STDC__=1
-D__stdcall=__attribute__((__stdcall__))
-D__cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x))
-D__i386__ -D_WIN32 -D__WINNT__ -D_X86_=1 -D__STDC__=1
-D__stdcall=__attribute__((__stdcall__))
-D__cdecl=__attribute__((__cdecl__)) -D__declspec(x)=__attribute__((x))
-D__i386 -D__WINNT -Asystem(winnt) -Acpu(i386) -Amachine(i386)
-D__EXCEPTIONS -remap -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__
-Di586 -Dpentium -D__i586 -D__i586__ -D__pentium -D__pentium__
-D__CYGWIN32__ -D__CYGWIN__ pbcctor.cc c:\tmp/cc1PfFX1.ii
GNU CPP version 2.95.2 19991024 (release) (80386, BSD syntax)
#include "..." search starts here:
#include <...> search starts here:
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/../../../../../include/g++-3
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/../../../../../include
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/../../../../i586-cygwin32/include
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/include
End of search list.
The following default directories have been omitted from the search path:
/usr/include
End of omitted list.
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/cc1plus.exe c:\tmp/cc1PfFX1.ii -quiet -dumpbase pbcctor.cc -version
-o c:\tmp/ccQoeol2.s
GNU C++ version 2.95.2 19991024 (release) (i586-cygwin32) compiled by GNU C
version 2.95.2 19991024 (release).
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/../../../../i586-cygwin32/bin/as.exe -o c:\tmp/ccMa0W1s.o
c:\tmp/ccQoeol2.s
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/collect2.exe -o pbcctor.exe
/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin32/
2.95.2/../../../../i586-cygwin32/lib/crt0.o
-L/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin3
2/2.95.2 -L/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib
-L/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin3
2/2.95.2/../../../../i586-cygwin32/lib
-L/Program/Cygnus/cygwin-b20/H-i586-cygwin32/bin/../lib/gcc-lib/i586-cygwin3
2/2.95.2/../../.. c:\tmp/ccMa0W1s.o -lstdc++ -lm -lgcc -lcygwin -luser32
-lkernel32 -ladvapi32 -lshell32 -lgcc
-----------------output of g++ -v pbcctor.cc -o pbcctor --------------
--
James Kanze mailto:kanze@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627