James Kanze
10/30/2008 10:30:00 AM
On Oct 29, 8:52 pm, "dasca...@gmail.com" <dasca...@gmail.com> wrote:
> On Oct 24, 8:12 pm, Jeff Newman <Jeffrey.M.New...@gmail.com> wrote:
[...concerning multiple entry points for destructors...]
> > The (snipped) report:
> > 3: 4: virtual ~blah()
> > 3: 5: {
> > 3: 6: };
> > branch 0 never executed
> > branch 1 never executed
> > call 2 never executed
> > branch 3 taken 0 (fallthrough)
> > branch 4 taken 2
> > call 5 never executed
> > branch 6 taken 0 (fallthrough)
> > branch 7 taken 1
> > call 8 never executed
> > -: 7:};
> It's most likely (given that you're using GCC) that it
> instantiates two destructors - one for if it is a non-virtual
> base class (which means that it calls its parent destructors)
> and when it is (which means that it does not call its parent
> destructors). Your virtual function table contains two
> functions too.
Either I've misunderstood what you wrote, or you got it wrong.
The different entry points used depend on whether the destructor
is for the most derived class or not; roughly speaking, calls
from outside go to one, and calls from a derived class
destructor go to the other. The difference is that the calls
from a derived class destructor must not call the destructors of
any virtual base classes; those from the most derived class must
call the destructors of any virtual base classes *after* having
called the destructors of the non-virtual base classes. (I
think that the words "in charge" appear in output of nm -C for
the constructor called when the class is the most derived
class.)
> If it's nonvirtual it should still generate both of them, but
> it might notice that it has no base classes and that they are
> equal, and hence merge them. It also might not generate one of
> them as nobody calls it. In case of virtual functions,
> somebody outside of your scope of compilation might call it
> anyway, so it has to generate it and put it in the virtual
> function table - so it has to be made, and then has uncalled
> code.
The not most derived class case is never called using virtual
function resolution, so it needed appear in the vtable.
> Could you try the test again using it as a virtual base in one
> subclass?
I think the test would have to be:
class B {} ;
class D1 : public virtual B {} ;
class D2 : public D1 {} ;
, then call the destructor on an instance of D1 and on an
instance of D2. If I understand it corretly, this should call
both destructors of D1.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34