Topic: Use of standard exception classes


Author: "Bradd W. Szonye" <bradds@ix.netcom.com>
Date: 1996/04/27
Raw View
On Tuesday, April 23, 1996, Bob Friesenhahn wrote...
> With your proposed scheme, how do you tell which library generated the
> exception, especially when you have no control over third-party exception
> classes?
[Moderator's note: quoting edited by moderator. -fjh.]

This is a situation where (as frequently occurs) we are at the mercy of
our 3rd-party library vendors. A good library will use one of two
mechanisms to identify its exceptions:

(1) Its own derivations from the standard exception classes, as I
described in my previous post
(2) Sensible use of the what() function/member of the exception classes

Either is suitable for describing the source or nature of the exception.

I think the standard hierarchy provides two excellent mechanisms for
identifying exceptions, through subclassing/inheritance and a descriptive
string. Either is plenty sufficient, provided your library takes advantage
of it. If your library vendors are not so considerate, either find a
workaround or find a different vendor. Those are choices we always have,
standards notwithstanding.
--
Bradd W. Szonye (bradds@ix.netcom.com), Doubleplus Corporation

"To chill or to pop a cap in my dome, whoomp, there it is."
   -- Hamlet, Prince of Denmark

---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Bradd W. Szonye" <bradds@ix.netcom.com>
Date: 1996/04/21
Raw View
On Monday, April 15, 1996, Bob Friesenhahn wrote...
> Kevin Cline wrote:
>
> > Can someone on the committee indicate whether it was the committee's
> > intention for the standard exception class hierarchy to be used in
> > general C++ programming, or whether the intention was for the standard
> > exception class hierarchy to be reserved to the Standard C++ library?
> >
> > Another developer on our team has asked
> >   How can we be sure that ANSI C++ library callbacks work
> >   correctly in the face of exceptions?  What if ANSI C++
> >   library code catches *our* exception?
>
> A further consideration is that often it is valuable to know what
> body of code generated an exception.  If all exeptions are derived
> from the same base class, then it will be impossible to tell if
> an exception occurred in standard library code, user code, or some
> third party library. An additional level of derivation could be
> used to satisfy this requirement, but since the standard exception
> classes have already been defined, there is no satisfactory place
> to insert the additional derivation.
>
> By using a different base class for each seperately maintained body
> of code, it will be possible to provide handlers for each code body
> with the additional maintenance expense of maintaining the additional
> catch blocks.
>
> Bob

I don't see this as a real problem (determining if the user's code
generated the exception). Consider this:

class user_defined_exception: virtual public exception { ... };
class user_logic_error: virtual public logic_error, virtual public
user_definded_exception { ... };

... catch (logic_error* e)
{
 if (dynamic_cast<user_defined_exception>(e)) ...
}

This will tell you if the logic error you caught was one defined in your
own code or somebody else's.




[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Bob Friesenhahn <bfriesen@cyberramp.net>
Date: 1996/04/23
Raw View
Bradd W. Szonye wrote:
>

> > By using a different base class for each seperately maintained body
> > of code, it will be possible to provide handlers for each code body
> > with the additional maintenance expense of maintaining the additional
> > catch blocks.
>
> I don't see this as a real problem (determining if the user's code
> generated the exception). Consider this:
>
> class user_defined_exception: virtual public exception { ... };
> class user_logic_error: virtual public logic_error, virtual public
> user_definded_exception { ... };
>
> ... catch (logic_error* e)
> {
>         if (dynamic_cast<user_defined_exception>(e)) ...
> }
>
> This will tell you if the logic error you caught was one defined in your
> own code or somebody else's.

Yes, but in real-world programs, we see multiple libraries written by
various third parties.  It is useful to know if an exception is derived
from a networking library, vs a general purpose class library, vs the
STD C++ library (possibly in that order).  Ideally, one expects that
exception handlers have some hope of recovering from the problem.
The information that a "logic error" occured is much less significant
than the knowledge that a network connection has broken as a result.

With your proposed scheme, how do you tell which library generated the
exception, especially when you have no control over third-party exception
classes?

I think that this is why we don't see a mandate to trivialize exception
classes.  Exception classes should be designed to adequately represent
the problems they report such that the problems can be adequately resolved.
Problem reporting on the order of "Bus error, core dumped" is not adequate
for serious programs.

Bob
--
Bob Friesenhahn
bfriesen@cyberramp.net (Home)
thefuzz@bix.com        (On BIX)
http://www.cyberramp.net/~bfriesen


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Rob Stewart <stew@datalytics.com>
Date: 1996/04/18
Raw View
Brian Glendenning wrote:
>
> In a different topic, I'm confused about the different purpose ascribed to
> exceptions derived from logic_error:
> [snip]
>
> and runtime_error:
> [snip]
>
> It seems to me that with this wording most exceptions should be derived from
> runtime_error.
> However, basic_string<...>::remove(size_type pos = 0, size_type n = npos),
> for example, throws out_of_range (derived from logic error).
>
> Unless the program only runs with manifest constants, it can't detect this
> problem before the program executs:
>         cin >> pos; mystring.remove(pos);
>
> So why does it throw a logic_error rather than a runtime_error? Thanks!
>
> (I'm also interested in learning whether it's a good idea to derive our
> exceptions from standard exceptions).
>

Your code should have encountered that condition during
development, or you should have seen it coming, so you should
have logic built in to supply correct values to remove in all
cases.

--
Robert Stewart  | My opinions are usually my own.
Datalytics, Inc. | stew@datalytics.com
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kcline@spdmail.spd.dsccc.com (Kevin Cline)
Date: 1996/04/12
Raw View
In "The Standard C++ Library" on page 65, Plauger wrote:

  "I strongly encourage you to follow the lead of the Standard C++
   library in the use of exceptions:
   * Throw only objects of one or more classes derived from [exception]

Page 19-1 of the 4/95 version of the draft says "The Standard C++
library provides classes to be used to report errors in C++ programs."

But in section 19.1.1 of the same draft it says:

"The class exception defines the base class for the  types  of  objects
 thrown  as  exceptions by *C++ Standard library components*, and certain
 expressions, to report errors detected during program execution."

Can someone on the committee indicate whether it was the committee's
intention for the standard exception class hierarchy to be used in
general C++ programming, or whether the intention was for the standard
exception class hierarchy to be reserved to the Standard C++ library?

Another developer on our team has asked
  How can we be sure that ANSI C++ library callbacks work
  correctly in the face of exceptions?  What if ANSI C++
  library code catches *our* exception?

Is this a problem, or are library functions required to reraise any
exceptions thrown by client code?

Kevin Cline
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Nathan Myers <ncm@cantrip.org>" <ncm@cantrip.org>
Date: 1996/04/13
Raw View
Kevin Cline wrote:
>
> In "The Standard C++ Library" on page 65, Plauger wrote:
>
>   "I strongly encourage you to follow the lead of the Standard C++
>    library in the use of exceptions:
>    * Throw only objects of one or more classes derived from [exception]
>
> Page 19-1 of the 4/95 version of the draft says "The Standard C++
> library provides classes to be used to report errors in C++ programs."
>
> But in section 19.1.1 of the same draft it says:
>
> "The class exception defines the base class for the  types  of  objects
>  thrown  as  exceptions by *C++ Standard library components*, and certain
>  expressions, to report errors detected during program execution."
>
> Can someone on the committee indicate whether it was the committee's
> intention for the standard exception class hierarchy to be used in
> general C++ programming, or whether the intention was for the standard
> exception class hierarchy to be reserved to the Standard C++ library?


In discussion that led to the current formulation for the standard
exception types, it became clear that they are not general enough
for all uses in user code; the committee agreed that it was sufficient
to standardize just what is needed for the standard library.

So use your own exception types, if you like; if you derive from
a standard exception, you probably should use virtual derivation
for reasons John Skaller seems always happy to explain.


> Another developer on our team has asked
>   How can we be sure that ANSI C++ library callbacks work
>   correctly in the face of exceptions?  What if ANSI C++
>   library code catches *our* exception?
>
> Is this a problem, or are library functions required to reraise any
> exceptions thrown by client code?

I assume that by "library callbacks" s/he means member functions
invoked by library components?

Bad things happen if you throw during copy construction or destruction
of a vector element.  Don't let it happen.  (Yes, I know this is easier
said than done.  Still.)   There are lots of things in the library that
could break if a user object (or even a standard object!) throws during
a standard function.  Probably there are some places where it would be
safe, but the committee hasn't identified them except in iostreams, where
it's specified under what circumstances exceptions are caught and rethrown.

Nathan Myers
ncm@cantrip.org  http://www.cantrip.org/


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bglenden@colobus.aoc.nrao.edu (Brian Glendenning)
Date: 1996/04/14
Raw View
In a different topic, I'm confused about the different purpose ascribed to
exceptions derived from logic_error:

 "The class logic_error defines the type of objects thrown as exceptions
 to report errors presumably *detectable before the program executes*,
 such as violations of logical preconditions or invariants."

and runtime_error:

 "The class runtime_error defines the type of objects thrown as
 exceptions to report errors presumably only detectable when the program
 executes."

It seems to me that with this wording most exceptions should be derived from
runtime_error.
However, basic_string<...>::remove(size_type pos = 0, size_type n = npos),
for example, throws out_of_range (derived from logic error).

Unless the program only runs with manifest constants, it can't detect this
problem before the program executs:
 cin >> pos; mystring.remove(pos);

So why does it throw a logic_error rather than a runtime_error? Thanks!

(I'm also interested in learning whether it's a good idea to derive our
exceptions from standard exceptions).

Brian
--
        Brian Glendenning - National Radio Astronomy Observatory
bglenden@nrao.edu              Socorro NM               (505) 835-7347
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: gregor@netcom.com (Greg Colvin)
Date: 1996/04/14
Raw View
In article <9604121530.AA08606@sun132.spd.dsccc.com>
kcline@spdmail.spd.dsccc.com (Kevin Cline) writes:

>In "The Standard C++ Library" on page 65, Plauger wrote:
>
>  "I strongly encourage you to follow the lead of the Standard C++
>   library in the use of exceptions:
>   * Throw only objects of one or more classes derived from [exception]
>

Good advice.

>Page 19-1 of the 4/95 version of the draft says "The Standard C++
>library provides classes to be used to report errors in C++ programs."
>

True.

>But in section 19.1.1 of the same draft it says:
>
>"The class exception defines the base class for the  types  of  objects
> thrown  as  exceptions by *C++ Standard library components*, and certain
> expressions, to report errors detected during program execution."
>

Also true.

>Can someone on the committee indicate whether it was the committee's
>intention for the standard exception class hierarchy to be used in
>general C++ programming, or whether the intention was for the standard
>exception class hierarchy to be reserved to the Standard C++ library?
>

The intention was for the exception class hierarchy to serve well as
a basis for your own exception classes and as all the concrete exception
classes the library itself needs.  You can derive from exception, which is
almost an abstract class, or you can derive from its derivatives.

>Another developer on our team has asked
>  How can we be sure that ANSI C++ library callbacks work
>  correctly in the face of exceptions?  What if ANSI C++
>  library code catches *our* exception?
>

Not to worry.

>Is this a problem, or are library functions required to reraise any
>exceptions thrown by client code?
>

Client exceptions are intended to be pass through library code uncaught, or
at least reraised.

Greg Colvin
gregor@netcom.com
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@Eng.sun.com (Steve Clamage)
Date: 1996/04/15
Raw View
gregor@netcom.com (Greg Colvin) writes:

>>Another developer on our team has asked
>>  How can we be sure that ANSI C++ library callbacks work
>>  correctly in the face of exceptions?  What if ANSI C++
>>  library code catches *our* exception?
>>

>Not to worry.

>>Is this a problem, or are library functions required to reraise any
>>exceptions thrown by client code?
>>

>Client exceptions are intended to be pass through library code uncaught, or
>at least reraised.

I don't find that requirement in the draft. Perhaps I missed it.

In general, it seems to me that if a callback function throws an
exception that must be diagnosed as due to that callback and not to
anything else, that exception should not be derived from other
exceptions. Otherwise ALL exception-handling code must be rather
elaborate just in case some such callback might be involved (e.g.,
in a library you use but didn't write).

Every exception handler would have to determine whether the actual
exception was in fact derived from the exception it thought it
was handling, and rethrow it instead of handling it. (The current
function might not call a callback function, but one of the functions
it does call might have done so.) If you have to write all your code
like that, why use exception hierarchies at all?

I suspect it is typically the case that the callback can in fact throw
a derived exception without causing any difficulities. The callback
is in a sense part of the implementation of the called function,
and the problem it finds typically can be thought of as coming from
the called function.

For example, consider a "get_data" function that has takes a callback
to retrieve bytes from somewhere. If the callback encounters an error,
it is probably sufficient to throw an exception the get_data function
might have thrown on its own. The caller of get_data likely doesn't
care which sub-function found the problem, but only whether the
call succeeded or what class of error was found.

--
Steve Clamage, stephen.clamage@eng.sun.com


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/04/15
Raw View
kcline@spdmail.spd.dsccc.com (Kevin Cline) writes:

>In "The Standard C++ Library" on page 65, Plauger wrote:
>
>  "I strongly encourage you to follow the lead of the Standard C++
>   library in the use of exceptions:
>   * Throw only objects of one or more classes derived from [exception]
>
>Page 19-1 of the 4/95 version of the draft says "The Standard C++
>library provides classes to be used to report errors in C++ programs."
>
>But in section 19.1.1 of the same draft it says:
>
>"The class exception defines the base class for the  types  of  objects
> thrown  as  exceptions by *C++ Standard library components*, and certain
> expressions, to report errors detected during program execution."

Section 19.1/1 (that is, section 19.1 paragraph 1) of the Jan 96 draft
states it more clearly:

|   19.1  Exception classes                           [lib.std.exceptions]
|
| 1 The Standard C++ library provides classes to be used to report certain
|   errors (_lib.res.on.exception.handling_)  in  C++  programs.

Note that section 19.1.1 is

|  19.1.1  Class logic_error                            [lib.logic.error]

which is probably not the section to which you were referring.  I find
it helpful to use `.' for sub-section numbers and `/' for paragraph
numbers, to avoid confusion.

>Can someone on the committee indicate whether it was the committee's
>intention for the standard exception class hierarchy to be used in
>general C++ programming, or whether the intention was for the standard
>exception class hierarchy to be reserved to the Standard C++ library?

I believe the emphasis on "by *C++ Standard library components*" was
simply intended to stress the point that other C++ code didn't have
to throw only objects derived from class `exception' (as I believe was
mooted in some previous designs for C++ exception handling).
It was not intended to suggest that user's C++ code could not do so,
only that they did not have to do so.  I guess this wording was
recognized as being confusing, since it has now been replaced.

I would still consider Plauger's advice quoted above as good advice.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Bob Friesenhahn <bfriesen@cyberramp.net>
Date: 1996/04/15
Raw View
Kevin Cline wrote:

> Can someone on the committee indicate whether it was the committee's
> intention for the standard exception class hierarchy to be used in
> general C++ programming, or whether the intention was for the standard
> exception class hierarchy to be reserved to the Standard C++ library?
>
> Another developer on our team has asked
>   How can we be sure that ANSI C++ library callbacks work
>   correctly in the face of exceptions?  What if ANSI C++
>   library code catches *our* exception?

A further consideration is that often it is valuable to know what
body of code generated an exception.  If all exeptions are derived
from the same base class, then it will be impossible to tell if
an exception occurred in standard library code, user code, or some
third party library. An additional level of derivation could be
used to satisfy this requirement, but since the standard exception
classes have already been defined, there is no satisfactory place
to insert the additional derivation.

By using a different base class for each seperately maintained body
of code, it will be possible to provide handlers for each code body
with the additional maintenance expense of maintaining the additional
catch blocks.

Bob
--
Bob Friesenhahn
bfriesen@cyberramp.net (Home)
thefuzz@bix.com        (On BIX)
http://www.cyberramp.net/~bfriesen
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/04/15
Raw View
In article <316F646D.552DF1DD@cantrip.org> "Nathan Myers
<ncm@cantrip.org>" <ncm@cantrip.org> writes:

|> > Another developer on our team has asked
|> >   How can we be sure that ANSI C++ library callbacks work
|> >   correctly in the face of exceptions?  What if ANSI C++
|> >   library code catches *our* exception?
|> >
|> > Is this a problem, or are library functions required to reraise any
|> > exceptions thrown by client code?

|> I assume that by "library callbacks" s/he means member functions
|> invoked by library components?

|> Bad things happen if you throw during copy construction or destruction
|> of a vector element.

Does this imply that `vector< string >' is unsafe.  As far as I can
tell, it is impossible to write a conforming basic_string that can
guarantee never to through a `bad_alloc' during copy.  (Even if
basic_string normally uses a shared implementation, the semantic
constraints on pointer validity after reserve would seem to exclude any
sharing of the implementation in this case.  So maybe the restriction
is that you are not allowed to change the size of `vector< string >' if
`reserve' has been called on any of its elements.)

|> Don't let it happen.  (Yes, I know this is easier
|> said than done.  Still.)   There are lots of things in the library that
|> could break if a user object (or even a standard object!) throws during
|> a standard function.  Probably there are some places where it would be
|> safe, but the committee hasn't identified them except in iostreams, where
|> it's specified under what circumstances exceptions are caught and rethrown.

If I understand what you are saying correctly, we should not use
exceptions with the standard library, because it will not be required
to be exception safe.  And just when everyone has been telling me that
I cannot avoid exceptions, because the standard library is throwing
them all over the place.  (And yes, I know.  This latter statement is
just what everyone is saying; in fact, there is almost nowhere in the
standard library where you cannot avoid exceptions if you want to.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, itudes et rialisations en logiciel orienti objet --
                -- A la recherche d'une activiti dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: gregor@netcom.com (Greg Colvin)
Date: 1996/04/17
Raw View
In article <4kr853$785@engnews1.Eng.Sun.COM> clamage@Eng.sun.com (Steve
Clamage) writes:
>gregor@netcom.com (Greg Colvin) writes:
>
>>Client exceptions are intended to be pass through library code uncaught, or
>>at least reraised.
>
>I don't find that requirement in the draft. Perhaps I missed it.
>

Its not in the draft, just me misinterpreting a sentence I misremembered from
an earlier draft, said sentence long since removed. Oh well.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]