<html>
<head>
<title>Deletion Traits Proposal (J16/03-0091 WG21/N1508)</title>
<meta content="HTML Tidy for Windows (vers 1st February 2003), see www.w3.org" name="generator">
<style type="text/css"> body { background-color: white; }
	:link { color: blue }
	:visited { color: purple }
	</style>
</head>
<body>
<h1>Proposal to add Deletion Traits to the Standard Library</h1>
<p><tt>Doc. no.:&nbsp;J16/03-0091 = WG21/N1508</tt><br>
<tt>Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13 September 2003</tt><br>
<tt>Project:&nbsp;&nbsp;Programming Language C++</tt><br>
<tt>Reply To:&nbsp;Bronek Kozicki &lt;</tt><tt><a href="mailto:brok@rubikon.pl"><em>brok@rubikon.pl</em></a></tt><tt>&gt;</tt></p>
<h2>Contents</h2>
<p><a href="#motivation">1. Motivation</a><br>
<a href="#design">2. Design, requirements and proposal text</a><br>
<a href="#proposal">3. Proposal</a><br>
&nbsp;&nbsp;<a href="#is_safely_destructible">3.1.
<tt>is_safely_destructible</tt></a><br>
&nbsp;&nbsp;<a href="#has_virtual_destructor">3.2.
<tt>has_virtual_destructor</tt></a><br>
<a href="#discussion">4. Discussion</a><br>
&nbsp;&nbsp;<a href="#alternatives">4.1. Alternatives</a><br>
&nbsp;&nbsp;<a href="#rationale">4.2. Rationale</a><br>
&nbsp;&nbsp;<a href="#otheruse">4.3. Other uses of proposed
traits</a><br>
<a href="#references">5. References</a><br>
<a href="#acknowledgements">6. Acknowledgements</a></p>
<h2><a name="motivation"></a>1. Motivation</h2>
<p>This proposal should be considered&nbsp;as addition to "Type
Traits Proposal", available in document N1424 [<a href=
"#ref_1" #ref_1??>1</a>] wrote by John Maddock. Main point of presented
proposal is to enable detection in compile time if particular
design requirement has been met in class design. This requirement
is <em>ability to safely destroy object</em> or in other words
<em>obey Liskov Substitution Principle in regard to object
destruction</em> . This is particularly important in generic
programming, where specific properties (or applicability for
specific purpose) of class being used may remain unknown at the
point of object creation, pointer cast or deletion. Currently there
are no means in language to protect against class of problems
presented bellow (assuming weak coupling between parts of presented
code):</p>
<pre>
template &lt;typename BASE, typename DERIVED&gt;
BASE* Create() {
&nbsp; return new DERIVED();
}
class Base{};
class Derived : public Base{};
Base* BaseFactory()
{
&nbsp; return Create&lt;Base, Derived&gt;();
}
void BaseOwner()
{
&nbsp; Base* b = BaseFactory();
&nbsp; // ...
&nbsp; delete b;
&nbsp; // undefined behaviour per clause 5.3.5/3 of C++ Standard
}
</pre>
<p>Following proposal is an attempt to deliver tools which 
can be used by generic programs to ensure well defined behaviour when objects of 
unknown type are being dynamically created, passed
between loosely-coupled parts of software and then deleted.</p>
<h2><a name="design"></a>2. Design, requirements and proposal
text</h2>
<p>Proposed traits share design constraints presented by John
Madock in type traits proposal [<a href="#ref_1">1</a>], as well as
parts of proposal text. Proposed traits fall in unary type traits,
type properties category of type traits proposal.&nbsp;Proposed
traits are using <tt>integral_constant</tt> template class, which
is part of type traits proposal.</p>
<h2><a name="proposal"></a>3. Proposal</h2>
<p>Two different traits are being proposed, where each could be
used to impose different set of restritions on class design -
namely <tt>is_safely_destructible</tt> (author of this proposal
believes that better name could be invented) and
<tt>has_virtual_destructor</tt>. It's important to note that these
traits cannot be implemented without compiler support; currently
there are no means in C++ language necessary to implement them. For
this reason there are no existing implementations, nor usage
experience. At the end of this paper sample usage of proposed
traits can be found. Another important point is that these traits
will remove some freedom from the programmer on class design, as
properties being inspected by traits are currently unavailable to
class user; however author of this proposal believes that discussed
properties belong to class interface (not implementation) and thus
giving this access will not break <EM>separate interface from
implementation</EM> rule. For the same reason, these traits can be used
to circumvent "as if" rule. Proposed traits do not introduce
runtime overhead; these traits are providing static type
properties, thus their values are static const, defined at compile
time. This proposal does not change existing language rules, nor
syntax or meaning of existing keywords.</p>
<h3><a name="is_safely_destructible"></a>3.1.
<tt>is_safely_destructible</tt></h3>
<pre>
template &lt;class T&gt; struct is_safely_destructible{
&nbsp; static const bool value = implementation_defined;
&nbsp; typedef bool value_type;
&nbsp; typedef integral_constant&lt;value_type, value&gt; type;
&nbsp; operator type()const;
}
</pre>
<p><tt>value</tt> is defined to be 
false for any class which inherits publicly available, non-virtual destructor; 
it's true otherwise. Class is said to inherit publicly available non-virtual 
destructor, if any of its public base classes has publicly accessible destructor 
which is not virtual. Note: this trait does not imply that class is polymorphic; 
per presented above rule, value of this trait is also true for class which has 
public non-virtual destructor, but does not inherit publicly from any other 
class having such destructor. In other words: this trait inspects not class 
alone, but root of its inheritance hierarchy.
It's believe of author of this proposal, that publicly inherited
classes should be considered part of class interface, thus this
proposal will not break <EM>separate interface from implementation</EM>
rule. This trait does not undisclose property of class if it is on
top of inheritance hierarchy or inherits from other class/es, as
long as it does not inherit destructors which can be used to delete
object causing undefined behaviour per clause 5.3.5/3. This trait
is mostly useful at point of object construction, ie. where dynamic
type of object being created is known at compile time, to ensure
well-defined behaviour during object deletion, where its known that
object ownership will be passed to pointer to any (unknown at point
of object construction) of its base classes.</p>
<p>Examples:</p>
<pre>
&nbsp; class Base1{protected: ~Base1();};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Base1&gt;::value == true;
&nbsp;&nbsp;&nbsp; // class Base1 does not inherit from any other class
&nbsp; class Derived1 : public Base1{};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived1&gt;::value == true;
&nbsp;&nbsp;&nbsp; // Derived1 inherits from Base1, which does not have public destructor
&nbsp; class Derived2 : public Base1{public: virtual ~Derived2();};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived2&gt;::value == true;
&nbsp;&nbsp;&nbsp; // As Derived1
&nbsp; class Base2{public: ~Base2();};
&nbsp;&nbsp;&nbsp;is_safely_destructible&lt;Base2&gt;::value == true;
&nbsp;&nbsp;&nbsp; // As Base1
&nbsp; class Derived3 : protected Base2 {public: virtual ~Derived3();};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived3&gt;::value == true;
&nbsp;&nbsp;&nbsp; // Base2 is not public base class of Derived3
&nbsp; class Derived4 : public Derived3, public Base1 {};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived4&gt;::value == true;
&nbsp;&nbsp;&nbsp; // base class Derived3 has virtual destructor
&nbsp;&nbsp;&nbsp; // and base class Base1 does not have public destructor
&nbsp; class Derived5 : public Base2{public: virtual ~Derived5();};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived5&gt;::value == false;
&nbsp;&nbsp;&nbsp; // inherits Base2::~Base2 , which is public and not virtual
&nbsp; class Base3 {protected: virtual ~Base3();};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Base3&gt;::value == true;
&nbsp;&nbsp;&nbsp; // Base3::~Base3 is not public
&nbsp; class Derived6 : private Base2{};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived6&gt;::value == true;
&nbsp;&nbsp;&nbsp; // Derived6 does not inherit publicly from Base2
&nbsp; class Derived7 : public boost::noncopyable{};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived7&gt;::value == true;
&nbsp;&nbsp;&nbsp; // boost::noncopyable does not have public destructor
&nbsp; class Derived8 : public Base2{protected: ~Derived8();};
&nbsp;&nbsp;&nbsp; is_safely_destructible&lt;Derived8&gt;::value == false ;
&nbsp;&nbsp;&nbsp; // inherits Base2::~Base2 , which is public and not virtual
</pre>
<p>Class <tt>boost::noncopyable</tt> is part of boost library
[<a href="#ref_2">2</a>].</p>
<p>This proposal does not protect against situations where object
is being deleted by friend class/function, or using <tt>delete
this;</tt> idiom. Such code is considered part of 
class implementation, thus no solution is necessary. In cases where programmer
 wants to ensure additional protection (not incuring
runtime cost), <tt>has_virtual_destructor</tt> trait (presented
below) is applicable.</p>
<h3><a name="has_virtual_destructor"></a>3.2.
<tt>has_virtual_destructor</tt></h3>
<pre>
template &lt;class T&gt; struct has_virtual_destructor{
&nbsp; static const bool value = implementation_defined;
&nbsp; typedef bool value_type;
&nbsp; typedef integral_constant&lt;value_type, value&gt; type;
&nbsp; operator type()const;
}
</pre>
<p><tt>value</tt> is defined to be true if class has virtual
destructor (no matter its access level); false otherwise. Author of
this proposal believes that polymorphism of class in regard to its
destructor is part of class interface (not implementation detail),
and thus this trait does not break <EM>separate interface from
implementation</EM> rule. This trait is mostly useful at two points of
the program:</p>
<ul type="disc">
<li>where ownership of dynamically
  created object is passed to pointer of one of its base classes 
<li>where dynamically 
created object is being deleted through
pointer to some of its base classes</li></ul>
<p>Examples (class definitions as above):</p>
<pre>
&nbsp; has_virtual_destructor&lt;Base1&gt;::value == false;
&nbsp; has_virtual_destructor&lt;Derived4&gt;::value == true;
&nbsp; has_virtual_destructor&lt;Base2&gt;::value == false;
&nbsp; has_virtual_destructor&lt;Base3&gt;::value == true;
&nbsp; has_virtual_destructor&lt;Derived7&gt;::value == false;
</pre>
<h2><a name="discussion"></a>4. Discussion</h2>
<p>Meaning of proposed trait <tt>is_safely_destructible</tt> is that dynamically
created object of given class can be safely (ie. not invoking undefined 
behaviour, per clause 5.3.5/3, first sentence) destroyed using pointer to any of 
its base classes. This allows class user to impose restrictions on class design, 
but offers most complete solution to given problem. These restrictions 
are being imposed not only on class alone, but also on all classes
it publicly derives from. To release these restrictions, trait
<tt>has_virtual_destructor</tt> can be used in most situations,
namely at the point of pointer cast to pointer to base class or at
the point of object deletion.</p>
<h3><a name="alternatives"></a>4.1. Alternatives</h3>
<p>Other possible solutions (presented here for discussion, but not
proposed in this document) are:</p>
<ul type="disc">
<li>detect at compile time whether the pointer being 
  delete'd is to polymorphic class and (at the same time) 
  
<li>the static type of pointer is to a class that has no virtual
destructor and make it illegal.</li></ul>
<p>This is not a good solution, as it would make illegal code that
is perfectly legal currently (when dynamic type of pointee is the
same as the static type of pointer, ie. polymorphic class is not
abstract). This is also not a full solution, as type of pointed
class might not be polymorphic, and under such condition possible
undefined behaviour would remain undetected. It is possible (but
not proposed in this paper) to add more rules to the language,
like:</p>
<ul type="disc">
<li>make definition of abstract class without virtual 
  destructor ill-formed 
  
<li>make illegal cast to pointer to non-polymorphic class from
pointer to polymorphic class</li></ul>
<p>but such rules would make invalid many programs, which 
currently are perfectly valid and do not expose undefined behaviour. In
opinion of author, this is definitely not a way to go.</p>
<h3><a name="rationale"></a>4.2. Rationale</h3>
<p>Proposed solution is based on assumption that at the point of
dynamic object creation, there usually is strategy of its
destruction. Possible strategies are:</p>
<ol type="1">
<li><p>own (do not pass ownership) the object for its whole lifetime,
and destroy it using pointer to static type identical to dynamic
type of pointee (ie. object being created). In such case there is
no need to impose any additional (besides those already imposed by
C++ language, ie. accessibility of destructor at the point of
object deletion) restriction on said class. Proposed traits have no
value if case this strategy has been chosen, because problem these
traits are designed to solve, does not appear. This strategy has
been chosen by authors of smart pointer <tt>boost::shared_ptr</tt>
[<a href="#ref_3">3</a>] . Author of this proposal believes that
 similar strategy could be adopted by <tt>std::auto_ptr</tt>, and proposed traits could be used to 
  make&nbsp;implementation efficient when possible (intruducing very small runtime cost 
  for&nbsp;objects which are "safe to delete through pointer to every base class"). This addition
is left as an idea for another proposal.</p>
<li><p>pass ownership of the object using pointers to some predefined
set of classes (including predefined set of its base classes), or
destroy it using pointer to any of such predefined classes. Trait
<tt>has_virtual_destructor</tt> can be used to allow 
  verification at compile time that these predefined base classes have virtual 
  destructors. This trait can be used at the point of object construction (verifying 
  predefined set of base classes), destruction (verifying static type of object pointer), or cast statement (at
the point where ownership of object is being passed to pointer to
its base class) . Example trait usage:</p>
<pre>
template &lt;typename BASE, typename DERIVED&gt;
BASE* create() {
&nbsp;&nbsp;static_assert(has_virtual_destructor&lt;BASE&gt;::value, "bad cast");
&nbsp;&nbsp;return new DERIVED();
}
class Base{}; class Derived : public Base{};
int main() {
Base* b = create&lt;Base, Derived&gt;();&nbsp; // static assertion
//...
delete b;
}
</pre>
<p><tt>static_assert</tt> is part of different proposal[<a href=
"#ref_4" #ref_4??>4</a>].</p>
<p>Please note that base class used to cast pointer object being
created is know at the point of object construction. Thus
<tt>has_virtual_destructor</tt> can be used here, to ensure
well-defined behaviour at the point of its destruction. Problem
with this trait is that it requires predefined set of base classes
at point of object construction, thus it introduces strong coupling
between class interface and point of its construction. Trait
<tt>is_safely_destructible</tt> can be used to avoid it.</p>
<li><p>pass ownership of the objects to loosely-coupled part 
  of program, which may further cast it to unknown (at the point where
objects is being created or passed) class. In this case creator of
object may use <tt>is_safely_destructible</tt> trait in regard to
dynamic class type (at point of its construction) to ensure that no
matter how object is being cast, its destruction will not expose
undefined behaviour.</p>
<pre>
class BaseA{public: virtual ~BaseA(){}}; class BaseB{};
class Derived : public BaseA, public BaseB{};
template &lt;typename CLASS&gt;
std::auto_ptr&lt;CLASS&gt; create() {
&nbsp;&nbsp;static_assert(is_safely_destructible&lt;CLASS&gt;::value, "unsafe class");
&nbsp;&nbsp;return new CLASS();
}
int main() {
std::auto_ptr&lt;BaseB&gt; = create();&nbsp; // static assertion
//...
}
</pre>
<p>Please note, that at the point of object construction only
dynamic type of object is known; function <tt>create</tt> is then
passing ownership of the object to its client, presuming that
client will cast this object to some (unknown at the point of
object construction) type. Please note that this sample code is
very simplified; in real-world code there would be very weak
coupling between creator and its clients, thus definition of
dynamic type could be unavailable from client code, and at the same
time creator would not know interfaces being implemented by class
just created. Use of <tt>is_safely_destructible</tt> allows creator
to ensure well defined behaviour during object destruction, no
matter how its going to be used by its new owner. Following code is
example of loosely-coupled class factory, which may benefit from
trait <tt>is_safely_destructible</tt>.</p>
<pre>
class factory : boost::noncopyable {
public:
&nbsp; template &lt;class Product&gt;
&nbsp; static bool register_class (std::string const&amp; identifier)
&nbsp; {
&nbsp;&nbsp;&nbsp; instance().creators[identifier] = &amp;create&lt;Product&gt;;
&nbsp;&nbsp;&nbsp; return true;
&nbsp; }
&nbsp; template &lt;class ProductBase&gt;
&nbsp; static bool create(std::string const&amp; identifier, std::auto_ptr&lt;ProductBase&gt;&amp; dest)
&nbsp; {
&nbsp;&nbsp;&nbsp; create_map::const_iterator i = instance().creators.find(identifier);
&nbsp;&nbsp;&nbsp; if (i == instance().creators.end())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;
&nbsp;&nbsp;&nbsp; std::auto_ptr&lt;base&gt; product(i-&gt;second());
&nbsp;&nbsp;&nbsp; if (ProductBase* b = dynamic_cast&lt;ProductBase*&gt;(product.get()))
&nbsp;&nbsp; &nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; product.release();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dest.reset(b);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;
&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; return false;
&nbsp; }
private:
&nbsp; factory() {}
~factory() {}
&nbsp; static factory&amp; instance()
&nbsp; {
&nbsp;&nbsp;&nbsp; static factory instance;
&nbsp;&nbsp;&nbsp; return instance;
&nbsp; }
&nbsp; class base {public: virtual ~base() {}};
&nbsp; typedef std::auto_ptr&lt;base&gt; (*create_function)();
&nbsp; typedef std::map&lt;std::string, create_function&gt; create_map;
&nbsp; template &lt;class Product&gt;
&nbsp; static std::auto_ptr&lt;base&gt; create()
&nbsp; {
&nbsp;&nbsp;&nbsp; struct derived : public Product, public base {};
&nbsp;&nbsp;&nbsp; static_assert(has_virtual_destructor&lt;Product&gt;::value), "Given class does not have virtual destructor")
// This assert is satisfied even if Product inherits public, non-virtual destructor
&nbsp;&nbsp;&nbsp; static_assert(is_safely_destructible&lt;derived&gt;::value, "Unable to safely inherit from given class");
// This assert fully verifies that Product class can be safely derived from
&nbsp;&nbsp;&nbsp; return std::auto_ptr&lt;base&gt;(new derived);
&nbsp; }
&nbsp; create_map creators;
};
class Shape {public: virtual ~Shape() {} /* ... */};
class Circle : public Shape {/* ... */};
factory::register_class&lt;Circle&gt;("circle");
// This code compiles fine
class Horse {public: virtual ~Horse() {} /* ... */};
class Donkey {public: ~Donkey() {} /* ... */}
class Mule : public Horse , public Donkey {/* ... */};
factory::register_class&lt;Mule&gt;("mule")
// Forces instantiation of factory::create&lt;Mule&gt; ,
// which defines struct base : public Mule, public base
// and triggers static assertion on is_safely_destructible&lt;derived&gt;
</pre>
<p>Class factory presented above was orginally wrote by Richard
Smith [<a href="#ref_5">5</a>], and modified by author&nbsp;of this
proposal as an example of traits usage.</p></li></ol>
<h3><a name="#otheruse">4.3. Other uses of proposed traits</a></h3>
<p>Trait <tt>is_safely_destructible</tt>can used to verify that
class can be safely used as a base class:</p>
<pre>
template &lt;typename T&gt; class is_safe_as_base{
&nbsp;&nbsp; struct A : public T {};
public:
&nbsp;&nbsp; typedef bool value_type;
&nbsp;&nbsp; static const value_type value = is_safely_destructible&lt;A&gt;::value;
&nbsp;&nbsp; typedef integral_constant&lt;value_type,value&gt; type;
&nbsp;&nbsp; operator type()const;
};
</pre>

<h2><a name="#references"></a>5. References</h2>
<p><a name="#ref_1"></a>[1]&nbsp;<a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1424.htm">http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1424.htm</a><br>
<a name="#ref_2"></a>[2]&nbsp;<a href="http://www.boost.org/libs/utility/utility.htm#Class_noncopyable">http://www.boost.org/libs/utility/utility.htm#Class_noncopyable</a><br>
<a name="#ref_3"></a>[3]&nbsp;<a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm">http://www.boost.org/libs/smart_ptr/shared_ptr.htm</a><br>
<a name="#ref_4"></a>[4]&nbsp;<a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1381.htm">http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1381.htm</a><br>
<a name="#ref_5"></a>[5]&nbsp;<a href="http://groups.google.pl/groups?as_umsgid=Pine.LNX.4.55.0309040946040.18458@sphinx.mythic-beasts.com">
http://groups.google.pl/groups?as_umsgid=Pine.LNX.4.55.0309040946040.18458@sphinx.mythic-beasts.com</a></p>
<h2><a name="acknowledgements"></a>6. Acknowledgements</h2>
<p> Many thanks to David Abrahams, John Maddock, Witold
Kuzminski and my wife Malgosia</p>
<p></p>
</body>
</html>
