This is the mail archive of the gcc-bugs@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]

g++: incorrect implicit copy constructor


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


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