Smart pointer and utility changes related to adding checked_delere and checked_array_delete

[SVN r10189]
This commit is contained in:
Beman Dawes 2001-05-22 18:58:21 +00:00
parent 851052fcca
commit e35f91a70a
3 changed files with 114 additions and 6 deletions

31
checked_delete_test.cpp Normal file
View File

@ -0,0 +1,31 @@
// Boost checked_delete test program ---------------------------------------//
// (C) Copyright Beman Dawes 2001. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright
// notice appears in all copies. This software is provided "as is" without
// express or implied warranty, and with no claim as to its suitability for
// any purpose.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 21 May 01 Initial version (Beman Dawes)
#include <boost/utility.hpp> // for checked_delete
// This program demonstrates compiler errors when trying to delete an
// incomplete type.
namespace
{
class Incomplete;
}
int main()
{
Incomplete * p;
boost::checked_delete(p); // should cause compile time error
Incomplete ** pa;
boost::checked_array_delete(pa); // should cause compile time error
return 0;
} // main

View File

@ -11,6 +11,9 @@
// Classes appear in alphabetical order
// Revision History
// 21 May 01 checked_delete() and checked_array_delete() added (Beman Dawes,
// suggested by Dave Abrahams, generalizing idea from Vladimir Prus)
// 21 May 01 made next() and prior() inline (Beman Dawes)
// 26 Jan 00 protected noncopyable destructor added (Miki Jovanovic)
// 10 Dec 99 next() and prior() templates added (Dave Abrahams)
// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes)
@ -22,12 +25,44 @@
#ifndef BOOST_UTILITY_HPP
#define BOOST_UTILITY_HPP
#include <boost/config.hpp>
#include <boost/config.hpp> // broken compiler workarounds
#include <boost/static_assert.hpp> // broken compiler workarounds
#include <cstddef> // for size_t
#include <utility> // for std::pair
namespace boost
{
// checked_delete() and checked_array_delete() -----------------------------//
// verify that types are complete for increased safety
template< typename T >
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200
inline void checked_delete(T const volatile * x)
# else
inline void checked_delete(T /*const volatile*/ * x)
# endif
{
# if !defined(__BORLANDC__) || __BORLANDC__ > 0x0551
BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
// of instantiation
# endif
delete x;
}
template< typename T >
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200
inline void checked_array_delete(T const volatile * x)
# else
inline void checked_array_delete(T /*const volatile*/ * x)
# endif
{
# if !defined(__BORLANDC__) || __BORLANDC__ > 0x0551
BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
// of instantiation
# endif
delete [] x;
}
// next() and prior() template functions -----------------------------------//
@ -41,10 +76,10 @@ namespace boost
// Contributed by Dave Abrahams
template <class T>
T next(T x) { return ++x; }
inline T next(T x) { return ++x; }
template <class T>
T prior(T x) { return --x; }
inline T prior(T x) { return --x; }
// class noncopyable -------------------------------------------------------//

View File

@ -16,10 +16,50 @@
<h2>Contents</h2>
<ul>
<li>Function templates <a href="#checked_delete">checked_delete() and
checked_array_delete()</a></li>
<li>Function templates <a href="#functions next">next() and prior()</a></li>
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
</ul>
<h2> Function templates <a name="checked_delete">checked_delete</a>() and
checked_array_delete()</h2>
<p>Deletion of a pointer to an incomplete type is an unsafe programming practice
because there is no way for the compiler to verify that the destructor is indeed
trivial.&nbsp; The checked_delete() and checked_array_delete() function
templates simply <b>delete</b> or <b>delete[]</b> their argument, but also
require that their argument be a complete type.&nbsp; They issue an appropriate
compiler error diagnostic if that requirement is not met.&nbsp; A typical
implementation is shown; other implementations may vary:</p>
<pre> template&lt; typename T &gt;
inline void checked_delete(T const volatile * x)
{
BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
// of instantiation
delete x;
}
template&lt; typename T &gt;
inline void checked_array_delete(T const volatile * x)
{
BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
// of instantiation
delete [] x;
}</pre>
<p>Contributed by Beman Dawes, based on a suggestion from Dave Abrahams,
generalizing an idea from Vladimir Prus, with comments from Rainer Deyke, John
Maddock, and others.</p>
<h3>Background</h3>
<p>The C++ Standard specifies that delete on a pointer to an incomplete types is
undefined behavior if the type has a non-trivial destructor in&nbsp; [expr.delete]
5.3.5 paragraph.&nbsp; No diagnostic is required.&nbsp; Some but not all
compilers issue warnings if the type is incomplete at point of deletion.</p>
<h2> <a name="functions next">Function</a> templates next() and prior()</h2>
<p>Certain data types, such as the C++ Standard Library's forward and
@ -91,9 +131,11 @@ emphasize that it is to be used only as a base class.&nbsp; Dave Abrahams notes
concern about the effect on compiler optimization of adding (even trivial inline)
destructor declarations. He says &quot;Probably this concern is misplaced, because
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics.&quot;</p>
<h2>Function template tie()</h2>
<p>See <a href="tie.html">separate documentation</a>.</p>
<hr>
<p>Revised&nbsp; <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
-->08 March, 2001<!--webbot bot="Timestamp" endspan i-checksum="28780"
-->22 May, 2001<!--webbot bot="Timestamp" endspan i-checksum="13960"
-->
</p>
<p>© Copyright boost.org 1999. Permission to copy, use, modify, sell and