This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: Devirtualize virtual call hierarchy if just base dtor exists


On 10/22/2014 05:30 PM, Jonathan Wakely wrote:
On 22 October 2014 16:15, Martin LiÅka wrote:
Hello.

I've been playing with following example:

#include <stdlib.h>

class Base
{
public:
   virtual ~Base() {}
};

class Derived: public Base
{
};

#define N 1000

int main()
{
   Base **b = (Base **)malloc (sizeof(Base *) * N);
   for (unsigned i = 0; i < N; i++)
     b[i] = new Derived();

   for (unsigned i = 0; i < N; i++)
     delete b[i];

   return 0;
}

Where I would like to somehow give an advice to devirtualize machinery. My
motivation is to inline destruction in 'delete b[i]'.
'final' keyword does not solve my problem:

a.c:9:7: error: virtual function âvirtual Derived::~Derived()â
  class Derived: public Base
        ^
a.c:6:11: error: overriding final function âvirtual Base::~Base()â
    virtual ~Base() final {}

Virtual destructors are special, derived classes *must* override them,
so you can't make it final in the base class.

If I enclose my classes to anonymous namespace:

Procesing function int main()/172
   Targets of polymorphic call of type 0:struct Base token 2
     Contained in type:struct Base at offset 0
     This is a complete list. (derived types included)
        virtual {anonymous}::Base::~Base()/164 virtual
{anonymous}::Derived::~Derived()/183

More than one likely target

Presumably because the dynamic type of *b[i] could be Base or Derived,
and the compiler can't know until it checks it. Does it make any
difference if you make Base an abstract class? In that case the
compiler should know that the dynamic type of *b[i] cannot be Base, so
must be a Derived.


Looks that addition of an abstract method to Base class really helps:

  for (unsigned i = 0; i < N; i++)
    delete b[i];
  4006a0:	48 8b 3b             	mov    (%rbx),%rdi
  4006a3:	48 85 ff             	test   %rdi,%rdi
  4006a6:	74 05                	je     4006ad <main+0x4d>
public:
  virtual ~Base() {}
  virtual void Foo() = 0;
};

class Derived final: public Base
  4006a8:	e8 83 ff ff ff       	callq  400630 <_ZdlPv@plt>
  4006ad:	48 83 c3 08          	add    $0x8,%rbx

Thank you,
Martin


My question is how can one help compiler if he knows that a class hierarchy
is complete and there's no destructor except the virtual for base class?


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