Devirtualize virtual call hierarchy if just base dtor exists
Martin Liška
mliska@suse.cz
Wed Oct 22 16:16:00 GMT 2014
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?
More information about the Gcc
mailing list