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

Re: Implicit copy constructor for virtual bases


> I suppose I would vote for option b, documentation.

Ok, so I propose this patch below. If accepted, I'd also like to relax
the test case, and only test that the base is copied at all.

This patch also updates the documentation somewhat with regard to the
'evolving language' claims.

I'm not sure where implementation statements should go in the
documentation. Various language standards leave things
implementation-defined, and then require implementations to actually
document how they've defined it. I was going to collect them for C++,
but gave up on page 53...

Regards,
Martin

Index: ChangeLog
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ChangeLog,v
retrieving revision 1.3271
diff -u -r1.3271 ChangeLog
--- ChangeLog	1999/03/24 10:01:53	1.3271
+++ ChangeLog	1999/03/25 21:59:42
@@ -1,3 +1,7 @@
+Thu Mar 25 22:53:27 1999  Martin von Löwis  <loewis@informatik.hu-berlin.de>
+
+	* gcc.texi (Copy Assignment): New node.
+
 1999-02-24  Mike Stump  <mrs@wrs.com>
 
 	* arm/aout.h (DBX_OUTPUT_MAIN_SOURCE_FILENAME): Fix quoting.
Index: cp/ChangeLog
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/ChangeLog,v
retrieving revision 1.953
diff -u -r1.953 ChangeLog
--- ChangeLog	1999/03/24 03:01:01	1.953
+++ ChangeLog	1999/03/25 22:00:09
@@ -1,3 +1,7 @@
+1999-03-25  Martin von Löwis  <loewis@informatik.hu-berlin.de>
+
+	* gxxint.texi: Remove old discussion on copying virtual bases.
+
 1999-03-24  Martin von Löwis  <loewis@informatik.hu-berlin.de>
 
 	* class.c (finish_struct_1): Always reset TYPE_FIELDS for empty
Index: gcc.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/gcc.texi,v
retrieving revision 1.19
diff -u -r1.19 gcc.texi
--- gcc.texi	1999/03/10 23:22:31	1.19
+++ gcc.texi	1999/03/25 21:59:50
@@ -1643,15 +1643,16 @@
 @cindex misunderstandings in C++
 @cindex surprises in C++
 @cindex C++ misunderstandings
-C++ is a complex language and an evolving one, and its standard definition
-(the ANSI C++ draft standard) is also evolving.  As a result,
-your C++ compiler may occasionally surprise you, even when its behavior is
-correct.  This section discusses some areas that frequently give rise to
-questions of this sort.
+C++ is a complex language and an evolving one, and its standard
+definition (the ISO C++ standard) was only recently completed.  As a
+result, your C++ compiler may occasionally surprise you, even when its
+behavior is correct.  This section discusses some areas that frequently
+give rise to questions of this sort.
 
 @menu
 * Static Definitions::  Static member declarations are not definitions
 * Temporaries::         Temporaries may vanish before you expect
+* Copy Assignment::     Copy Assignment operators copy virtual bases twice
 @end menu
 
 @node Static Definitions
@@ -1743,6 +1744,61 @@
 String& tmp = strfunc ();
 charfunc (tmp);
 @end example
+
+@node Copy Assignment
+@subsection Implicit Copy-Assignment for Virtual Bases
+
+When a base class is virtual, only one subobject of the base class
+belongs to each full object. Also, the constructors and destructors are
+invoked only once, and called from the most-derived class. However, such
+objects behave undefined when being copied. For example:
+
+@example
+struct Base@{
+  char *name;
+  Base(char *n) : name(strdup(n))@{@}
+  Base& operator= (const Base& other)@{
+   free (name);
+   name = strdup (other.name);
+  @}
+@};
+
+struct A:virtual Base@{
+  int val;
+  A():Base("A")@{@}
+@};
+
+struct B:virtual Base@{
+  int bval;
+  B():Base("B")@{@}
+@};
+
+struct Derived:public A, public B@{
+  Derived():Base("Derived")@{@}
+@};
+
+void func(Derived &d1, Derived &d2)
+@{
+  d1 = d2;
+@}
+@end example
+
+The C++ standard specifies that @samp{Base::Base} is only called once
+when constructing or copy-constructing a Derived object. It is
+unspecified whether @samp{Base::operator=} is called more than once when
+the implicit copy-assignment for Derived objects is invoked (as it is
+inside @samp{func} in the example).
+
+g++ implements the "intuitive" algorithm for copy-assignment: assign all
+direct bases, then assign all members. In that algorithm, the virtual
+base subobject can be encountered many times. In the example, copying
+proceeds in the following order: @samp{val}, @samp{name} (via
+@code{strdup}), @samp{bval}, and @samp{name} again.
+
+If application code relies on copy-assignment, a user-defined
+copy-assignment operator should be provided. With such an operator, the
+application can define whether and how the virtual base subobject is
+assigned.
 
 @node Protoize Caveats
 @section Caveats of using @code{protoize}
Index: cp/gxxint.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/gxxint.texi,v
retrieving revision 1.15
diff -u -r1.15 gxxint.texi
--- gxxint.texi	1998/12/16 21:15:31	1.15
+++ gxxint.texi	1999/03/25 22:00:13
@@ -23,7 +23,6 @@
 * Access Control::              
 * Error Reporting::             
 * Parser::                      
-* Copying Objects::             
 * Exception Handling::          
 * Free Store::                  
 * Mangling::  Function name mangling for C++ and Java
@@ -931,7 +930,7 @@
 DECL, use @code{cp_error_at} and its ilk; to indicate which argument you want,
 use @code{%+D}, or it will default to the first.
 
-@node Parser, Copying Objects, Error Reporting, Top
+@node Parser, Exception Handling, Error Reporting, Top
 @section Parser
 
 Some comments on the parser:
@@ -1022,33 +1021,7 @@
 
 Unlike the others, this ambiguity is not recognized by the Working Paper.
 
-@node  Copying Objects, Exception Handling, Parser, Top
-@section Copying Objects
-
-The generated copy assignment operator in g++ does not currently do the
-right thing for multiple inheritance involving virtual bases; it just
-calls the copy assignment operators for its direct bases.  What it
-should probably do is:
-
-1) Split up the copy assignment operator for all classes that have
-vbases into "copy my vbases" and "copy everything else" parts.  Or do
-the trickiness that the constructors do to ensure that vbases don't get
-initialized by intermediate bases.
-
-2) Wander through the class lattice, find all vbases for which no
-intermediate base has a user-defined copy assignment operator, and call
-their "copy everything else" routines.  If not all of my vbases satisfy
-this criterion, warn, because this may be surprising behavior.
-
-3) Call the "copy everything else" routine for my direct bases.
-
-If we only have one direct base, we can just foist everything off onto
-them.
-
-This issue is currently under discussion in the core reflector
-(2/28/94).
-
-@node  Exception Handling, Free Store, Copying Objects, Top
+@node  Exception Handling, Free Store, Parser, Top
 @section Exception Handling
 
 Note, exception handling in g++ is still under development.  



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