Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Any way to detect the absense of virtual destructor in base class?

Reply
Thread Tools

Any way to detect the absense of virtual destructor in base class?

 
 
Qi
Guest
Posts: n/a
 
      11-24-2011
The full question:
Any portable and standard way to detect the absence of virtual
destructor in base class?

Boost has some type traits for that, but they are intrinsic and rely
on the compilers internal implementation.

Here is some sample code,

class A {
// no virtual destructor
};

class B : public A {
// some data here, whatever
};

A * a = new B;
delete a;

If B has virtual destructor, the behavior of "delete a" is UB. (I
spent half an hour on this issue).
If B has no virtual dtor, memory leak!

So the ideal way is, whenever newing a B like that, a static assert
failure or runtime failure is thrown to indicate A needs a virtual dtor.

Is it possible?
I doubt that, but it's quite annoying to debug that problem in case
I forget to give A a virtual dtor.

If it's impossible, any suggestion on how to avoid forgetting give
base class a virtual dtor?


Thanks


--
WQ
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      11-24-2011
On 24.11.2011 10:20, Qi wrote:
> The full question:
> Any portable and standard way to detect the absence of virtual
> destructor in base class?
>
> Boost has some type traits for that, but they are intrinsic and rely
> on the compilers internal implementation.
>
> Here is some sample code,
>
> class A {
> // no virtual destructor
> };
>
> class B : public A {
> // some data here, whatever
> };
>
> A * a = new B;
> delete a;
>
> If B has virtual destructor, the behavior of "delete a" is UB. (I
> spent half an hour on this issue).
> If B has no virtual dtor, memory leak!
>
> So the ideal way is, whenever newing a B like that, a static assert
> failure or runtime failure is thrown to indicate A needs a virtual dtor.
>
> Is it possible?
> I doubt that, but it's quite annoying to debug that problem in case
> I forget to give A a virtual dtor.
>
> If it's impossible, any suggestion on how to avoid forgetting give
> base class a virtual dtor?


Why are you using a raw pointer?

Use `std::unique_ptr` or `std::shared_ptr`, or e.g. `boost::shared_ptr`.

These smart pointers remember the proper derived class destruction to
use, freeing you having to have a virtual destructor.


Cheers & hth.,

- Alf
 
Reply With Quote
 
 
 
 
Vladimir Jovic
Guest
Posts: n/a
 
      11-24-2011
On 24/11/11 10:20, Qi wrote:
> The full question:
> Any portable and standard way to detect the absence of virtual
> destructor in base class?
>
> Boost has some type traits for that, but they are intrinsic and rely
> on the compilers internal implementation.
>
> Here is some sample code,
>
> class A {
> // no virtual destructor
> };
>
> class B : public A {
> // some data here, whatever
> };
>
> A * a = new B;
> delete a;
>
> If B has virtual destructor, the behavior of "delete a" is UB. (I
> spent half an hour on this issue).
> If B has no virtual dtor, memory leak!
>
> So the ideal way is, whenever newing a B like that, a static assert
> failure or runtime failure is thrown to indicate A needs a virtual dtor.
>
> Is it possible?
> I doubt that, but it's quite annoying to debug that problem in case
> I forget to give A a virtual dtor.
>
> If it's impossible, any suggestion on how to avoid forgetting give
> base class a virtual dtor?


That check would be more complex then adding the "virtual" keyword to
the destructor of the base class.

Anyway, here you are:

#include <boost/type_traits/has_virtual_destructor.hpp>
struct a
{
virtual ~a(){}
};
struct b
{
virtual ~b(){}
};

// ok
static_assert( boost::has_virtual_destructor<a>::value, "no virt
destructor" );
// error
static_assert( boost::has_virtual_destructor<b>::value, "no virt
destructor" );

int main()
{
}
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      11-24-2011
On 24 Nov., 10:20, Qi wrote:
> The full question:
> Any portable and standard way to detect the absence of virtual
> destructor in base class?


Since you said "standard way" and did not explicitly exclude C++2011:

#include <type_traits>

:::

std::has_virtual_destructor<YourType>::value

Cheers!
SG
 
Reply With Quote
 
Qi
Guest
Posts: n/a
 
      11-24-2011
On 2011-11-24 20:50, SG wrote:
> Since you said "standard way" and did not explicitly exclude C++2011:
>
> #include<type_traits>
>
> :::
>
> std::has_virtual_destructor<YourType>::value


Thanks

This, plus static assert, seems an elegant solution.

But,
1, Any equivalence in C++2003 ?
2, If not, any "standard" way to detect the compiler
supports only 03 or also supports 11? So I can have some
backward compatibility.


--
WQ
 
Reply With Quote
 
Qi
Guest
Posts: n/a
 
      11-24-2011
On 2011-11-24 17:35, Alf P. Steinbach wrote:
>
> Why are you using a raw pointer?
>
> Use `std::unique_ptr` or `std::shared_ptr`, or e.g. `boost::shared_ptr`.
>
> These smart pointers remember the proper derived class destruction to
> use, freeing you having to have a virtual destructor.


I'm a fan of scoped pointer (though not fan of shared pointer).
But raw pointer is still quite useful to me.


--
WQ
 
Reply With Quote
 
Qi
Guest
Posts: n/a
 
      11-24-2011
On 2011-11-24 17:45, Vladimir Jovic wrote:
> // ok
> static_assert( boost::has_virtual_destructor<a>::value, "no virt
> destructor" );
> // error
> static_assert( boost::has_virtual_destructor<b>::value, "no virt
> destructor" );


That Boost trait has some assumption on the compiler dependent
object binary layout, AFAIK.
So it's neither standard nor portable.


--
WQ
 
Reply With Quote
 
Marc
Guest
Posts: n/a
 
      11-24-2011
Qi wrote:

> 2, If not, any "standard" way to detect the compiler
> supports only 03 or also supports 11? So I can have some
> backward compatibility.


The value of the macro __cplusplus *should* do it.
 
Reply With Quote
 
Lee Steven
Guest
Posts: n/a
 
      11-25-2011
On Nov 24, 5:20*am, Qi <(E-Mail Removed)> wrote:
> The full question:
> Any portable and standard way to detect the absence of virtual
> destructor in base class?
>
> Boost has some type traits for that, but they are intrinsic and rely
> on the compilers internal implementation.
>
> Here is some sample code,
>
> class A {
> // no virtual destructor
>
> };
>
> class B : public A {
> // some data here, whatever
>
> };
>
> A * a = new B;
> delete a;
>
> If B has virtual destructor, the behavior of "delete a" is UB. (I
> spent half an hour on this issue).
> If B has no virtual dtor, memory leak!
>
> So the ideal way is, whenever newing a B like that, a static assert
> failure or runtime failure is thrown to indicate A needs a virtual dtor.
>
> Is it possible?
> I doubt that, but it's quite annoying to debug that problem in case
> I forget to give A a virtual dtor.
>
> If it's impossible, any suggestion on how to avoid forgetting give
> base class a virtual dtor?
>
> Thanks
>
> --
> WQ


Here, I think If A has no virtual dtor, memory leak!

 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      11-25-2011
Alf P. Steinbach <(E-Mail Removed)> wrote:
> Use `std::unique_ptr` or `std::shared_ptr`, or e.g. `boost::shared_ptr`.
>
> These smart pointers remember the proper derived class destruction to
> use, freeing you having to have a virtual destructor.


How exactly do they achieve that? If I do, for example, this:

std::unique_ptr<Base*> ptr = new Derived;

then how exactly is 'ptr' able to deduce the derived class destructor in
order to directly call it when it disposes of the object?

(And where would it store it anyways? I thought the whole idea with
std::unique_ptr is that its size is that of one pointer, hence making
it as efficient as a raw pointer.)

I wonder if you are being confused by shared_ptr (and possible other
smart pointers) being able to destroy an object even if they only see
a class declaration (rather than a definition), as long as the class was
fully declared at the point of construction of the pointer. (IOW the class
doesn't need to be fully declared at the place of destruction.) That's not
the same thing as a base-class type smart pointer being able to deduce
the derived-class type destructor.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Absense of bool AommiK C Programming 73 11-26-2007 08:03 AM
Can abstract base class have V-table?, Will the pointer to virtual destructor be entered into the virtual table? sojin C++ 12 04-07-2006 09:02 AM
Explicit destructor calls from inside base class destructor frs C++ 20 09-21-2005 09:22 AM
Format of compiler generated derived destructor when base has 'virtual ~base() throw():" qazmlp C++ 1 04-10-2005 03:09 PM
Virtual destructor for virtual base class? Chunhui Han C++ 2 06-24-2004 10:13 AM



Advertisments