mirror of
https://github.com/boostorg/boost.git
synced 2025-04-07 22:39:25 +00:00
Make reference and footnote links relative, update email address
[SVN r13413]
This commit is contained in:
parent
18bfac2409
commit
33f91b8002
1 changed files with 30 additions and 41 deletions
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<!-- saved from url=(0052)http://people.ne.mediaone.net/abrahams/abrahams.html -->
|
||||
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta name="generator" content="Microsoft FrontPage 5.0">
|
||||
<title>Exception-Safety in Generic Components</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta content="MSHTML 5.50.4522.1800" name="GENERATOR">
|
||||
|
@ -13,10 +13,8 @@
|
|||
|
||||
<h3 align="center">David Abrahams</h3>
|
||||
|
||||
<h3 align="center">Dragon Systems</h3>
|
||||
|
||||
<h3 align="center"><code><a href=
|
||||
"mailto:David_Abrahams@dragonsys.com">David_Abrahams@dragonsys.com</a></code></h3>
|
||||
<h3 align="center"><a href="mailto:david.abrahams@rcn.com">
|
||||
david.abrahams@rcn.com</a></h3>
|
||||
|
||||
<p><b>Abstract.</b> This paper represents the knowledge accumulated in
|
||||
response to a real-world need: that the C++ Standard Template Library
|
||||
|
@ -83,13 +81,13 @@
|
|||
an article by Tom Cargill <a title=
|
||||
"Tom Cargill, ``Exception Handling: A False Sense of Security'', C++ Report, Nov-Dec 1994"
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference4"><sup>[4]</sup></a>
|
||||
"#reference4"><sup>[4]</sup></a>
|
||||
in which he explores the problem of exception-safety for a generic stack
|
||||
template. In his article, Cargill raises many useful questions, but
|
||||
unfortunately fails to present a solution to his problem.<a title=
|
||||
"Probably the greatest impediment to a solution in Cargill's case was an unfortunate combination of choices on his part: the interface he chose for his container was incompatible with his particular demands for safety. By changing either one he might have solved the problem."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote1"><sup>1</sup></a>
|
||||
"#footnote1"><sup>1</sup></a>
|
||||
He concludes by suggesting that a solution may not be possible.
|
||||
Unfortunately, his article was read by many as ``proof'' of that
|
||||
speculation. Since it was published there have been many examples of
|
||||
|
@ -103,7 +101,7 @@
|
|||
comparable with that of calling a function <a title=
|
||||
"D. R. Musser, ``Introspective Sorting and Selection Algorithms'', Software-Practice and Experience 27(8):983-993, 1997."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference7"><sup>[7]</sup></a>.
|
||||
"#reference7"><sup>[7]</sup></a>.
|
||||
That alone gives programs using exceptions performance equivalent to that
|
||||
of a program which ignores the possibility of errors. Using exceptions can
|
||||
actually result in faster programs than ``traditional'' error
|
||||
|
@ -121,8 +119,7 @@
|
|||
local variables to be destroyed upon returning from a function:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
ErrorCode f( int& result ) // 1
|
||||
<pre>ErrorCode f( int& result ) // 1
|
||||
{ // 2
|
||||
X x; // 3
|
||||
ErrorCode err = x.g( result ); // 4
|
||||
|
@ -139,8 +136,7 @@ ErrorCode f( int& result ) // 1
|
|||
no code devoted to error handling visible:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
int f() // 1
|
||||
<pre>int f() // 1
|
||||
{ // 2
|
||||
X x; // 3
|
||||
int result = x.g(); // 4
|
||||
|
@ -180,7 +176,7 @@ int f() // 1
|
|||
exceptions.<a title=
|
||||
" It is usually inadvisable to throw an exception from a destructor in C++, since the destructor may itself be called during the stack-unwinding caused by another exception. If the second exception is allowed to propagate beyond the destructor, the program is immediately terminated."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote2"><sup>2</sup></a>
|
||||
"#footnote2"><sup>2</sup></a>
|
||||
The generic component might, in return, provide one of the following
|
||||
guarantees:
|
||||
|
||||
|
@ -208,8 +204,7 @@ int f() // 1
|
|||
the following example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class X>
|
||||
<pre>template <class X>
|
||||
void print_random_sequence()
|
||||
{
|
||||
std::vector<X> v(10); // A vector of 10 items
|
||||
|
@ -231,7 +226,7 @@ void print_random_sequence()
|
|||
title=
|
||||
"In practice of course, this function would make an extremely poor random sequence generator!"
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote3"><sup>3</sup></a>
|
||||
"#footnote3"><sup>3</sup></a>
|
||||
It is ``safe'' in the sense that it is not allowed to crash, but
|
||||
its output may be unpredictable.
|
||||
|
||||
|
@ -246,7 +241,7 @@ void print_random_sequence()
|
|||
map, and multimap provide the <i>strong</i> guarantee.<a title=
|
||||
"It is worth noting that mutating algorithms usually cannot provide the strong guarantee: to roll back a modified element of a range, it must be set back to its previous value using operator=, which itself might throw. In the C++ standard library, there are a few exceptions to this rule, whose rollback behavior consists only of destruction: uninitialized_copy, uninitialized_fill, and uninitialized_fill_n."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote4"><sup>4</sup></a>).
|
||||
"#footnote4"><sup>4</sup></a>).
|
||||
|
||||
<p>The <i>no-throw</i> guarantee is the strongest of all, and it says that
|
||||
an operation is guaranteed not to throw an exception: it always completes
|
||||
|
@ -256,7 +251,7 @@ void print_random_sequence()
|
|||
important for other reasons, as we shall see.<a title=
|
||||
"All type parameters supplied by clients of the C++ standard library are required not to throw from their destructors. In return, all components of the C++ standard library provide at least the basic guarantee."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote5"><sup>5</sup></a>
|
||||
"#footnote5"><sup>5</sup></a>
|
||||
|
||||
<h2>4 Legal Wrangling</h2>
|
||||
|
||||
|
@ -271,7 +266,7 @@ void print_random_sequence()
|
|||
title=
|
||||
"Similar arrangements might have been made in the C++ standard for many of the mutating algorithms, but were never considered due to time constraints on the standardization process."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote6"><sup>6</sup></a>
|
||||
"#footnote6"><sup>6</sup></a>
|
||||
|
||||
<h2>5 What level of exception-safety should a component specify?</h2>
|
||||
|
||||
|
@ -306,8 +301,7 @@ void print_random_sequence()
|
|||
new copy'' strategy described above:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class Container, class BasicOp>
|
||||
<pre>template <class Container, class BasicOp>
|
||||
void MakeOperationStrong( Container& c, const BasicOp& op )
|
||||
{
|
||||
Container tmp(c); // Copy c
|
||||
|
@ -315,7 +309,7 @@ void MakeOperationStrong( Container& c, const BasicOp& op )
|
|||
c.swap(tmp); // Cannot fail<a title=
|
||||
"Associative containers whose Compare object might throw an exception when copied cannot use this technique, since the swap function might fail."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote7"><sup>7</sup></a>
|
||||
"#footnote7"><sup>7</sup></a>
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
@ -325,7 +319,7 @@ void MakeOperationStrong( Container& c, const BasicOp& op )
|
|||
characteristics).<a title=
|
||||
"This suggests another potential use for the oft-wished-for but as yet unseen container traits<> template: automated container selection to meet exceptionsafety constraints."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote8"><sup>8</sup></a>
|
||||
"#footnote8"><sup>8</sup></a>
|
||||
|
||||
<h2>6 Should we take everything we can get?</h2>
|
||||
|
||||
|
@ -340,7 +334,7 @@ void MakeOperationStrong( Container& c, const BasicOp& op )
|
|||
title=
|
||||
"D. R. Musser, ``Introspective Sorting and Selection Algorithms'', Software-Practice and Experience 27(8):983-993, 1997."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference6"><sup>[6]</sup></a>,
|
||||
"#reference6"><sup>[6]</sup></a>,
|
||||
which represents a substantial improvement in worst-case complexity over
|
||||
the well-established <i>quicksort</i>.
|
||||
|
||||
|
@ -351,8 +345,7 @@ void MakeOperationStrong( Container& c, const BasicOp& op )
|
|||
simple representative case for maintaining invariants in larger systems:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// SearchableStack - A stack which can be efficiently searched
|
||||
<pre>// SearchableStack - A stack which can be efficiently searched
|
||||
// for any value.
|
||||
template <class T>
|
||||
class SearchableStack
|
||||
|
@ -378,8 +371,7 @@ class SearchableStack
|
|||
guarantee within the natural levels of safety provided by set and list:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class T> // 1
|
||||
<pre>template <class T> // 1
|
||||
void SearchableStack<T>::push(const T& t) // 2
|
||||
{ // 3
|
||||
set<T>::iterator i = set_impl.insert(t); // 4
|
||||
|
@ -415,7 +407,7 @@ void SearchableStack<T>::push(const T& t) // 2
|
|||
<code>set<T>::erase</code>.<a title=
|
||||
"One might be tempted to surround the erase operation with a try/catch block to reduce the requirements on set<T> and the problems that arise in case of an exception, but in the end that just begs the question. First, erase just failed and in this case there are no viable alternative ways to produce the necessary result. Second and more generally, because of the variability of its type parameters a generic component can seldom be assured that any alternatives will succeed."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote9"><sup>9</sup></a>
|
||||
"#footnote9"><sup>9</sup></a>
|
||||
|
||||
<li>Line 11: for the same reasons, we also depend on being able to pass
|
||||
the <code>i</code> to the <code>erase</code> function: we need the
|
||||
|
@ -466,8 +458,7 @@ void SearchableStack<T>::push(const T& t) // 2
|
|||
<code>new</code>, for which an instrumented replacement was supplied.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// Use this as a type parameter, e.g. vector<TestClass>
|
||||
<pre>// Use this as a type parameter, e.g. vector<TestClass>
|
||||
struct TestClass
|
||||
{
|
||||
TestClass( int v = 0 )
|
||||
|
@ -494,11 +485,10 @@ struct TestClass
|
|||
guarantee: <a title=
|
||||
"Note that this technique requires that the operation being tested be exception-neutral. If the operation ever tries to recover from an exception and proceed, the throw counter will be negative, and subsequent operations that might fail will not be tested for exception-safety."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote12"><sup>12</sup></a>
|
||||
"#footnote12"><sup>12</sup></a>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
extern int gThrowCounter; // The throw counter
|
||||
<pre>extern int gThrowCounter; // The throw counter
|
||||
void ThisCanThrow()
|
||||
{
|
||||
if (gThrowCounter-- == 0)
|
||||
|
@ -542,7 +532,7 @@ void StrongCheck(const Value& v, const Operation& op)
|
|||
To my knowledge, there are currently only two descriptions of STL
|
||||
exception-safety available. The original specification <a title=
|
||||
"D. Abrahams, Exception Safety in STLport" href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference2"><sup>[2]</sup></a>
|
||||
"#reference2"><sup>[2]</sup></a>
|
||||
for the reference exception-safe implementation of the STL is an informal
|
||||
specification, simple and self-explanatory (also verbose), and uses the
|
||||
<i>basic-</i> and <i>strong-</i>guarantee distinctions outlined in this
|
||||
|
@ -553,27 +543,27 @@ void StrongCheck(const Value& v, const Operation& op)
|
|||
<p>The description of exception-safety in the C++ Standard <a title=
|
||||
"International Standard ISO/IEC 14882, Information Technology-Programming Languages-C++, Document Number ISO/IEC 14882-1998"
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference1"><sup>[1]</sup></a>
|
||||
"#reference1"><sup>[1]</sup></a>
|
||||
is only slightly more formal, but relies on hard-to-read
|
||||
``standardese'' and an occasionally subtle web of implication.<a
|
||||
title=
|
||||
"The changes to the draft standard which introduced exception-safety were made late in the process, when amendments were likely to be rejected solely on the basis of the number of altered words. Unfortunately, the result compromises clarity somewhat in favor of brevity. Greg Colvin was responsible for the clever language-lawyering needed to minimize the extent of these changes."
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#footnote13"><sup>13</sup></a>
|
||||
"#footnote13"><sup>13</sup></a>
|
||||
In particular, leaks are not treated directly at all. It does have the
|
||||
advantage that it <i>is</i> the standard.
|
||||
|
||||
<p>The original reference implementation <a title=
|
||||
"B. Fomitchev, Adapted SGI STL Version 1.0, with exception handling code by D. Abrahams"
|
||||
href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference5"><sup>[5]</sup></a>
|
||||
"#reference5"><sup>[5]</sup></a>
|
||||
of the exception-safe STL is an adaptation of an old version of the SGI
|
||||
STL, designed for C++ compilers with limited features. Although it is not a
|
||||
complete STL implementation, the code may be easier to read, and it
|
||||
illustrates a useful base-class technique for eliminating
|
||||
exception-handling code in constructors. The full test suite <a title=
|
||||
"D. Abrahams and B. Fomitchev, Exception Handling Test Suite" href=
|
||||
"http://people.ne.mediaone.net/abrahams/abrahams.html#reference3"><sup>[3]</sup></a>
|
||||
"#reference3"><sup>[3]</sup></a>
|
||||
used to validate the reference implementation has been used successfully to
|
||||
validate all recent versions of the SGI STL, and has been adapted to test
|
||||
one other vendor's implementation (which failed). As noted on the
|
||||
|
@ -691,5 +681,4 @@ void StrongCheck(const Value& v, const Operation& op)
|
|||
were likely to be rejected solely on the basis of the number of altered
|
||||
words. Unfortunately, the result compromises clarity somewhat in favor of
|
||||
brevity. Greg Colvin was responsible for the clever language-lawyering
|
||||
needed to minimize the extent of these changes.
|
||||
|
||||
needed to minimize the extent of these changes.
|
Loading…
Add table
Reference in a new issue