From 7513716513354982949
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,5cc796235bc9d4d8
X-Google-Attributes: gidf78e5,public
X-Google-Thread: 109fba,5cc796235bc9d4d8
X-Google-Attributes: gid109fba,public
X-Google-Thread: fc772,5cc796235bc9d4d8
X-Google-Attributes: gidfc772,public
From: "greg" <dont@spam.me>
Subject: Re: Article on exceptions in January C++ Report
Date: 1998/02/24
Message-ID: <6cu53k$918@netlab.cs.rpi.edu>#1/1
X-Deja-AN: 328268375
References: <6cjhbk$ru6@netlab.cs.rpi.edu> <6cre6n$qbd@netlab.cs.rpi.edu>
X-Submission-Address: c++-submit@netlab.cs.rpi.edu
X-Original-Date: 23 Feb 1998 23:55:27 GMT
X-UID: 0000000001
X-Status: $$$T
X-Approved-For-Group: dietmar.kuehl@izb-soft.de comp.lang.c++.moderated
Organization: SuperNet Inc. +1.303.285.0194 Denver Colorado
X-Auth: none comp.lang.c++.moderated
Newsgroups: comp.lang.c++.moderated,comp.std.c++,comp.lang.c++
Originator: clamage@taumet



Tom McKearney <no@spam.com> wrote in article
<6cre6n$qbd@netlab.cs.rpi.edu>...
> Matt Austern wrote in message <6cjhbk$ru6@netlab.cs.rpi.edu>...
> <snip>...
> Pardon my ignorance, but can someone please instruct me on the
> definitions
> of various levels of exception safety?

Following is the summary that Dave Abrahams and I presented at the last 
committee meeting. Hope it helps. In our proposals we did not define any
levels per se, but simply made sure that the draft specified for every 
library function the conditions, if any, under which it could throw and 
the effects, if any, of an exception thrown through the function.

So what rules should the user of the library function follow for types
passed to the library?  A slightly simplified summary is:
 * your destructors must never, ever throw;
 * if your copy constructors and comparison functors never throw then
   then all the containers are safe, that is they won't throw unless
   a type passed into them does (including the allocator), and their 
   contents will be unchanged after the throw;
 * if your copy constructors can throw, then stick with lists, maps, 
   sets, and stacks, and don't do multiple-element inserts except on
   lists.

Greg Colvin

------------------------------------------------------------------------
In London we made some changes to the library to provide one exception 
safe container (list) and one exception safe function (swap).  This 
paper identifies the few changes remaining to provide the full degree of
exception safety proposed in J16/97-0048R1 = WG21/N1086R1. We remain 
convinced that without these changes the library does not yet specify 
sufficient exception safety.

One sticking point in London was the lack of a clear and simple 
statement of just what degree of safety the library should provide.  A 
slightly over-simplified statement of the post-London status quo is:
 * swap() is safe;
 * list is safe.

To be more precise:
 * swap() has no effects if it throws an exception, 
 * erasing elements off a list will not throw, and 
 * inserting elements on a list has no effects if it does throw.

To be even more precise:
 * swap() is safe on an associative container only if its Compare 
   object can be copied without throwing.

We propose to enlarge that statement to:
 * swap is safe;
 * list, map, set, multimap, and multiset are safe;
 * vector and deque are safe if they contain PODs;
 * stack and queue are safe;
 * iterators returned from standard containers are safe.

To be more precise: 
 * multiple-element insertions are safe only for list; 
 * an insert() or erase() on a vector or deque is safe only if it 
   contains a type which can be copied without throwing; 
 * pop_back() and pop_front() will not throw; 
 * push_back() and push_front() have no effects if they do throw; and 
 * an iterator returned from a standard container can be copied without 
   throwing.

The associative containers can be made safe almost easily as can list,  
and for the same reason: they are node-based, so any failure to 
construct a node simply leaves the container as it was, and given that 
destructors don't throw there is no reason for removing a node to fail.
However, for multiple-element operations the need to keep elements 
sorted makes full recovery from a throw impractical.

Vector and deque are array-based containers, and so cannot fully recover
when a contained type's copy operation throws, because of the need to 
copy elements when resizing or inserting. Objects like PODs, whose copy 
operations do not throw, are common enough that the more limited 
guarantee is still useful.  However, push and pop operations do not 
require copying existing elements, and so are safe even if copying 
throws, as are the adaptors that use those operations.

The iterators returned from standard containers need to be copyable 
without throwing so that it is possible to roll back insertions by 
calling erase().


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




