TITLE: exceptions and interfaces (Newsgroups: comp.lang.c++.moderated) AUTHOR: kanze@gabi-soft.fr (J. Kanze), 17 Jun 1996 I'd like to throw in an additional comment to the exception arguement, that occured to me when trying to make some legacy code exception safe. Exception safety must, in certain cases, involve the interface, particularly with regards to pointer ownership. If constructing an object involves a transfer of ownership, and the constructor may throw an exception, it is probable that it should in such cases delete the object whose ownership is being transfered; in general, it will not always be possible for the caller to do so. A simple example of the problem would be the CountedObjPtr described in section 14.5 of the Barton and Nackman. This variant of the counted pointer idiom is non-invasive, and obtains the actual counter (which must be shared between several CountedObjPtr's) from the heap. Which means that its constructor can throw at least bad_alloc. Now consider the typical use: CountedObjPtr< T > p = new T ; If the constructor for T throws an exception, there is no problem. But if the constructor for CountedObjPtr throws an exception, who deletes the new'ed T? The only object which has a pointer to it is the CountedObjPtr being constructed. This has two major consequences: 1. This behavior *must* be documented as part of the interface contract. The constructor of CountedObjPtr *will* delete the object if an exception occurs. (I can hardly think of a reasonable case where this would not be the correct action. It's interesting to note, however, that the counted_ptr class that was considered by the standards committee did NOT delete the object pointed to in this case.) 2. With current compilers, it totally wrecks havoc with the elegant implementation described by Barton and Nackman. In their implementation, the actual reference counter was managed by a separate class, which allocated the memory (and thus risked the exception) during the initialization of the object, before entering the body of the CountedObjPtr. The standards committee has extended the language to allow catching exceptions from the base class/member constructors, but there are very few, if any, compilers which support this yet. [ Here is an example of such code. -adc X::X( ... ) try : a(..), b(..), c(..), d(..) { // ... } catch(...) { // oops! } ] While point 2 is a real drag, its effects are localized (in the implementation of CountedObjPtr), and it will not be a problem in the final language. On the other hand, in all of the discussions concerning exception safety, I've never seen point 1 mentioned. Exception safety is not just a local issue; it must also affect the interface, and the way classes interact with one another.