C++ Logo

sg12

Advanced search

[ub] Non-virtual destructor call

From: Andrzej Krzemienski <akrzemi1_at_[hidden]>
Date: Fri, 13 Dec 2013 13:56:01 +0100
Hi Everybody,

The standard says (Sect 5.3.5, para 3) that "In the first alternative (*delete
object*), if the static type of the object to be deleted is different from
its dynamic type, the static type shall be a base class of the dynamic type
of the object to be deleted and the static type shall have a virtual
destructor or the behavior is undefined."

This requirement is sound in general, but it prevents certain usages that
although uncommon appear to be valid and could be allowed.

The usage I have in mind is what Mathew Wilson calls "veneers" (see
http://synesis.com.au/resources/articles/cpp/veneers.pdf). In short, if I
do not like that std::function when default constructed is something that
throws upon the call to operator(), I extend it as follows:

template <typename T>
struct Callback : std::function<void(T)>
{
  Callback() : std::function<void(T)> { [](T){/*ignore*/} } {}
};

I can pass it by value, convert to std::function without slicing, and it
looks it would be safe to do this:

std::function<void(T)> * fun = new Callback;
delete fun;

There is no harm, except that this is defined as UB. Could the rule be
relaxed to say that if the derived type is layout-compatible with the base
class and its destructor is implicitly declared or explicitly defaulted,
the behaviur is well defined?

Or is there a good reason for this restriction?

Regards,
&rzej

Received on 2013-12-13 13:56:03