Problem with virtual base class in gcc-2.95.2

llewelly@198.dsl.xmission.com llewelly@198.dsl.xmission.com
Fri Dec 31 20:54:00 GMT 1999


> Dear GCC developers,
>
> It seems that this code (three lines) is correct, but
>
> class A                    { public: A(int i)     {} };
> class B: public virtual A  { public: B(int i):A(i){} };
> class C: public         B  { public: C(int i):B(i){} };
 
The constructor of a virtual base class is called *directly* from the 
  constructor of the most derived class. This is very different from the  
  way non-virtual bases are constructed.
  
On line 2 of your code there is a call to A::A(int). However, A is a 
  virtual base of B, so A::A(int) will not be called from this point if   
  the B under construction is a subobject of a C.
    
Instead, when a C is constructed, A's constructor is called from C's 
  constructor on line 3. Since C's constructor does not specify a 
  particular constructor for A, the default constructor is called ...
  which doesn't exist, thus the error.

To see why this strange behavior is both necessary and desireable,
  examine the following diamond-shaped inheritance graph:

                         A
                       /   \
                      B0   B1
                       \   /
                         C

  class A {};
  class B0 :public virtual A {};
  class B1 :public virtual A {};
  class C  :public B0,public B1 {};

  Since A is a virtual base, an object of type C can contain one and
    only one subobject of type A (thus the diamond shaped graph).

  Suppose an object of type C is being constructed. Imagine what would
    happen if A's constructor was called in the same fashion as a
    constructor for a non-virtual base class. A's constructor would be
    called once from B0's constructor ... and once again from B1's
    constructor. The A subobject would be constructed twice, which 
    would almost certainly be wrong.

  Instead, A's constructor is called from the constructor of the most
    derived class: C.

(btw, I also once submitted a g++ bug report for this same behavior...
  only to discover, to my chagrin, that it was in fact the correct
  behavior.)
  
> 
> $ g++ -c a.c
> a.c: In method `C::C(int)':
> a.c:3: no matching function for call to `A::A ()'
> a.c:1: candidates are: A::A(int)
> a.c:1:                 A::A(const A &)
> 
> Is the code ill-formed or this is really gcc-2.95.2 bug?

The code is ill-formed.


  
  
  




More information about the Gcc-bugs mailing list