From: kanze@us-es.sel.de (James Kanze)
Subject: Re: Exception Specifications
Organization: SEL
	<1992Oct01.143355.27847@bnr.ca>
Date: 7 Oct 92 15:13:32


In article <1992Oct01.143355.27847@bnr.ca>, Matthew Holiday writes:

|> In article <1992Sep30.205656.10646@lucid.com>, jss@lucid.com (Jerry
|> Schwarz) writes:

|> |> At the moment X3J16 is considering the implications of exceptions
|> |> for stream classes.  Some think that streams should only
|> |> be able to throw a particular kind of exception (tentatively
|> |> named ios::failure). Others (including myself) feel that a stream
|> |> should be able to throw an arbitrary exception. Remember, users
|> |> can define their own kinds of streambufs, so X3J16 can't know in advance
|> |> what kinds of conditions they might want to report.  
|> |> 
|> |> My intuition (not based on experience I confess) is that in
|> |> general it is more important to get specific information about
|> |> the conditions that caused an exception than it it to know that
|> |> it in occured in some stream operation. That is, it is better to
|> |> know that there was an "out of memory" or "database corruption" problem
|> |> than it is to know that there was a problem while doing a stream
|> |> operation.  This leads me to the conclusion that the iostream library
|> |> should not use failure clauses.

|> One thing that bugs me about having "lots" of exception types that
|> could be thrown is the degree of coupling that will result between
|> parts of the program.

|> If an object can throw 18 exception types, then clients will need to
|> understand all those types, and their implications -- and perhaps
|> then, something of the internal workings of that object, in order to
|> understand how to respond to a particular exception.

|> It might be better to cause the functions in the objects interface
|> (the top level functions of the object) to throw only a limited set of
|> exceptions, perhaps only one, and handle all other exceptions
|> themselves (print an error message or log, take some constructive
|> action, etc.).  The client's response to failure of an object might be
|> to destroy and recreate the object, and reattempt the operation, or
|> call a "recover" function in that object, etc.

|> There is a measure of philosophical difference here.  If all parts of
|> the program are written by the same team, then the team can determine
|> the safe degree of coupling between objects and their clients.  On the
|> other hand, if a program is to be created from reusable (perhaps
|> third-party) software libraries, then coupling should be minimized --
|> otherwise, why use objects at all?

This leads to my basic premise.

Objects in a general library should not throw exceptions at all.  The
how and what of exception handling is *always* application specific,
and if a library like the iostream starts throwing exceptions, it
forces *all* applications that use it into its mould.

The solution I prefer is call-back functions.  The default failure
action is always to terminate the program with an error message.
Since this occurs near the point of the error, the error message can
actually be quite meaningful.  In failsafe applications, the user
replaces the default error function with one of his own, which may
very well (probably will) throw an exception.  This will be an
exception designed by the user however, and not one imposed by the
library.  The choice of whether one or many exception classes, etc.,
and in what class hierarchy they are, can then be made in an
application specific manner by the user.
--
James Kanze                     GABI Software, Sarl.
email: kanze@us-es.sel.de       8 rue du Faisan
                                67000 Strasbourg
                                France
Newsgroups: comp.std.c++