public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Non-default ctors, virtual base classes, & multiple inheritance all at once!
@ 2000-09-05 11:15 Benjamin Scherrey
  2000-09-06  3:27 ` Alexandre Oliva
  0 siblings, 1 reply; 6+ messages in thread
From: Benjamin Scherrey @ 2000-09-05 11:15 UTC (permalink / raw)
  To: gcc

    I'm having some trouble getting non-default constructors called for
virtual baseclasses in certain instances.. I've attached some code that
demonstrates this problem. In some cases, I can pass a parameter up the
tree to the virtual base class, in others, the default ctor is always
called even though my code clearly specifies the ctor taking a parm. Is
this a compiler bug or a language design issue?

    thanx & later,

        Ben Scherrey

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Non-default ctors, virtual base classes, & multiple inheritance all at  once!
  2000-09-05 11:15 Non-default ctors, virtual base classes, & multiple inheritance all at once! Benjamin Scherrey
@ 2000-09-06  3:27 ` Alexandre Oliva
  2000-09-06  8:39   ` Joe Buck
  2000-09-06  9:37   ` sidster
  0 siblings, 2 replies; 6+ messages in thread
From: Alexandre Oliva @ 2000-09-06  3:27 UTC (permalink / raw)
  To: scherrey; +Cc: gcc

On Sep  5, 2000, Benjamin Scherrey <scherrey@switchco.com> wrote:

> I can pass a parameter up the tree to the virtual base class, in
> others, the default ctor is always called even though my code
> clearly specifies the ctor taking a parm.  Is this a compiler bug or
> a language design issue?

The latter.  It is the most derived class that must construct all
virtual base classes, even indirect ones.  If it doesn't, default
constructors are used, even if other base classes specify constructor
arguments for virtual bases.

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Non-default ctors, virtual base classes, & multiple inheritance all at  once!
  2000-09-06  3:27 ` Alexandre Oliva
@ 2000-09-06  8:39   ` Joe Buck
  2000-09-06  9:37   ` sidster
  1 sibling, 0 replies; 6+ messages in thread
From: Joe Buck @ 2000-09-06  8:39 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: scherrey, gcc

> 
> On Sep  5, 2000, Benjamin Scherrey <scherrey@switchco.com> wrote:
> 
> > I can pass a parameter up the tree to the virtual base class, in
> > others, the default ctor is always called even though my code
> > clearly specifies the ctor taking a parm.  Is this a compiler bug or
> > a language design issue?
> 
> The latter.  It is the most derived class that must construct all
> virtual base classes, even indirect ones.  If it doesn't, default
> constructors are used, even if other base classes specify constructor
> arguments for virtual bases.

This is one of the major botches in C++.  The only way around it that will
scale is to have a policy that, whenever virtual base classes are used,
the virtual base must have a default constructor and this constructor must
be the one that is used in the constructor for any derived object that
uses the virtual base.  Otherwise you have a major violation of
encapsulation and all derived classes have to worry about initializing the
virtual base correctly, and if anyone makes a derived class that doesn't
do this, things don't work right.

The compiler, of course, has to support people who violate this design
rule.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Non-default ctors, virtual base classes, & multiple inheritance all at  once!
  2000-09-06  3:27 ` Alexandre Oliva
  2000-09-06  8:39   ` Joe Buck
@ 2000-09-06  9:37   ` sidster
  2000-09-06 20:00     ` (retracting my comment) " sidster
  1 sibling, 1 reply; 6+ messages in thread
From: sidster @ 2000-09-06  9:37 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: scherrey, gcc

Greetings,


* Alexandre Oliva (aoliva@redhat.com) [20000906 07:45]:
> On Sep  5, 2000, Benjamin Scherrey <scherrey@switchco.com> wrote:
> 
> > I can pass a parameter up the tree to the virtual base class, in
> > others, the default ctor is always called even though my code
> > clearly specifies the ctor taking a parm.  Is this a compiler bug or
> > a language design issue?
> 
> The latter.  It is the most derived class that must construct all
> virtual base classes, even indirect ones.  If it doesn't, default
> constructors are used, even if other base classes specify constructor
> arguments for virtual bases.


If I understand what you are suggesting correctly then it is
_impossible_ to get the desired behavior with the given code.

Since  template <typename X> class HoldX  has no knowledge of what
base classes  X  might have to even provide constructors to specify
them in its "mem-initializer-list".

In other words all template classes with template parameter classes
containing virtual bases classes (direct or indirect) are restricted
to using/initializing only the default constructors of these virtual
base classes.  ???

I'm not sure about you but this strikes me as /quite odd/!

If this is true ... then there is a HUGE limitation in the C++
language!


I don't think this makes sense at all.  Can you please provide us with
a reference to this behavior/limitation in the standard?


The only section I find is the following:


[12.6.2  Initializing bases and members]
//
//   Initialization shall proceed in the following order:
//
//   - First, and only for the constructor of the most derived class
//     as described below, virtual base classes shall be initialized
//     in the order they appear on a depth-first left-to-right
//     traversal of the directed acyclic graph of base classes, where
//     "left-to-right" is the order of appearance of the base class
//     names in the derived class base-specifier-list.


Which seems to be supporting your point.  Which, originally I wasn't too
sure if it actually meant *all virtual base classes* (including direct
and indirect).

But the more i read the above it is more clear that that is in-fact what
it means.


The only possible way of getting the intended behavior from the given
code would be to write a "wrapper" class to be the most derived class
and specify the desired constructors of the virtual base classes in its
"mem-initializer-list".

Eeeek!  Talk about a hack, error prone, tedious and a maintenance
nightmare!


Please correct me if i'm wrong.  Originally I was going to discard this
thread but now it's become more interesting :>


patrick
--
when i grow up i want to be a famous rock'n roll guitar player
      -- steve vai

^ permalink raw reply	[flat|nested] 6+ messages in thread

* (retracting my comment) Re: Non-default ctors, virtual base classes, & multiple inheritance all at  once!
  2000-09-06  9:37   ` sidster
@ 2000-09-06 20:00     ` sidster
  2000-09-06 20:42       ` Alexandre Oliva
  0 siblings, 1 reply; 6+ messages in thread
From: sidster @ 2000-09-06 20:00 UTC (permalink / raw)
  To: gcc; +Cc: Alexandre Oliva, scherrey

Greetings,

After thinking about this topic a bit more, I would like to retract my
comment associating the choice in the picking the default constructor
of virtual base classes in multiple inheritance instances to a
"limitation in the C++ language".


I apologize for drawing this rash conclusion.  If I had thought about
it a bit more I would've realized that the above 'policy' is the best
one possible.


Assume the following scenario:


// begin mtor2.cc

// sidster <patrick at boxsoft dot com>
//
#include <iostream>


   class A
   {
      int i;

    public:
      A( void )
         :
         i(0)
            { cout << "A(void)" << endl; };
      A(int _i)
         :
         i(_i)
            { cout << "A(int)" << endl; };
      A(float _f)
         :
         i((int)_f)
            { cout << "A(float)" << endl; };

      int
      get_value( void ) const
         { return this->i; };
   };


   class B
      :
      virtual public A
   {
    public:
      B(int _i)
         :
         A(_i)
            { cout << "B(int) : A(int)" << endl; };
   };

   class C
      :
      virtual public A
   {
    public:
      C(float _f)
         :
         A(_f)
            { cout << "C(float) : A(float)" << endl; };
   };

   class D
      :
      public B,
      public C
   {
    public:
      D( int _i, float _f )
         :
         B(_i),
         C(_f)
            { cout << "D(void) : B(int) , C(float)" << endl; };
   };

   class E
      :
      public B,
      public C
   {
    public:
      E( int _i, float _f )
         :
         B(_i),
         C(_f),
         A(_i)
            { cout << "E(void) : B(int) , C(float), A(int)" << endl; };
   };

   class F
      :
      public B,
      public C
   {
    public:
      F( int _i, float _f )
         :
         B(_i),
         C(_f),
         A(_f)
            { cout << "F(void) : B(int) , C(float), A(float)" << endl; };
   };


   int main( int, char** )
   {
      D d( 8, 4.7 );
      cout << "i = " << d.get_value() << endl;     // 0
      cout << "- - - - - - - - - - - -" << endl;

      E e( 18, 9.5 );
      cout << "i = " << e.get_value() << endl;     // 18
      cout << "- - - - - - - - - - - -" << endl;

      F f( 18, 9.5 );
      cout << "i = " << f.get_value() << endl;     // 9
      cout << "- - - - - - - - - - - -" << endl;

      return 0;
   }

// end mtor2.cc


How will the compiler know which constructor of class A to use when
instantiating an instance of class D?

Since only _one_ instance of class A is to be in D and since both
parent classes, B and C, call different constructors of class A?!

Which would _you_ pick?

So I assume the good people working on the C++ standard concluded that
the best policy is to call the default constructor of that virtual base
class unless otherwise specified.

Both classes, E and F, resolve this ambiguity by specifying which
constructor should be favored.


I am curious, does this sound about right?  Or are you all thinking
"what's this guy been smokin'"??



Be good,

(this discussion obviously should've been moved to some c++ news group a
 while back since it obviously has nothing to do with gcc.  However,
 since this'll most likely be the last bit in the thread i hope no one
 will be 'ticked off' at me for trying to clear things up.)


* sidster (patrick@mail.boxsoft.com) [20000906 09:50]:
> 
> Greetings,
> 
> 
> * Alexandre Oliva (aoliva@redhat.com) [20000906 07:45]:
> > 
> > The latter.  It is the most derived class that must construct all
> > virtual base classes, even indirect ones.  If it doesn't, default
> > constructors are used, even if other base classes specify constructor
> > arguments for virtual bases.
> 
> 
> If I understand what you are suggesting correctly then it is
> _impossible_ to get the desired behavior with the given code.
> 
> Since  template <typename X> class HoldX  has no knowledge of what
> base classes  X  might have to even provide constructors to specify
> them in its "mem-initializer-list".
> 
> In other words all template classes with template parameter classes
> containing virtual bases classes (direct or indirect) are restricted
> to using/initializing only the default constructors of these virtual
> base classes.  ???
> 
> I'm not sure about you but this strikes me as /quite odd/!
> 
> If this is true ... then there is a HUGE limitation in the C++
> language!
> 
> 
> I don't think this makes sense at all.  Can you please provide us with
> a reference to this behavior/limitation in the standard?
> 
> 
> The only section I find is the following:
> 
> 
> [12.6.2  Initializing bases and members]
> //
> //   Initialization shall proceed in the following order:
> //
> //   - First, and only for the constructor of the most derived class
> //     as described below, virtual base classes shall be initialized
> //     in the order they appear on a depth-first left-to-right
> //     traversal of the directed acyclic graph of base classes, where
> //     "left-to-right" is the order of appearance of the base class
> //     names in the derived class base-specifier-list.
> 
> 
> Which seems to be supporting your point.  Which, originally I wasn't too
> sure if it actually meant *all virtual base classes* (including direct
> and indirect).
> 
> But the more i read the above it is more clear that that is in-fact what
> it means.
> 
> 
> The only possible way of getting the intended behavior from the given
> code would be to write a "wrapper" class to be the most derived class
> and specify the desired constructors of the virtual base classes in its
> "mem-initializer-list".
> 
> Eeeek!  Talk about a hack, error prone, tedious and a maintenance
> nightmare!



patrick
--
when i grow up i want to be a famous rock'n roll guitar player
      -- steve vai

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: (retracting my comment) Re: Non-default ctors, virtual base classes, & multiple inheritance all at  once!
  2000-09-06 20:00     ` (retracting my comment) " sidster
@ 2000-09-06 20:42       ` Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2000-09-06 20:42 UTC (permalink / raw)
  To: sidster; +Cc: gcc, scherrey

On Sep  6, 2000, sidster <patrick@mail.boxsoft.com> wrote:

> I am curious, does this sound about right?

I think so.  They've probably considered checking the base
constructors to see if only one of them specifies a constructor for
the virtual base, but this would only work if all constructors were
defined in that translation unit.

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2000-09-06 20:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-09-05 11:15 Non-default ctors, virtual base classes, & multiple inheritance all at once! Benjamin Scherrey
2000-09-06  3:27 ` Alexandre Oliva
2000-09-06  8:39   ` Joe Buck
2000-09-06  9:37   ` sidster
2000-09-06 20:00     ` (retracting my comment) " sidster
2000-09-06 20:42       ` Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).