Topic: ubiquitous exception specs?


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/11/21
Raw View
dak <pierreba@poster.cae.ca> writes:

>Why shouldn't templates have exception specified ?  Saying that it depends on
>the types used in the template instance seems gibberish to me: you could say
>the same for any class that use any other class (eitehr publicly or in its
>implementation).

Part of the problem is that the C++ language is not powerful enough to
express the right exception specifications for even simple templates.
For example, what should the exception specification for the following
template be?

 template <class T> T add3 (T a, T b, T c) { return a + b + c; }

Using exception specifications is a trade-off, just like using
a strongly typed language is a trade-off.  Strong types are great
if the type system is powerful enough (e.g. it includes templates
or some equivalent functionality), but if it is not, they can
be a real straight-jacket.

A coding standard which required the use of exception specifications
on all templates would also be a straight-jacked, because it would
make it difficult or impossible to write/use a lot of simple and useful
templates.

Another part of the problem is that even if the C++ language
was powerful enough to express appropriate exception specifications for
templates, the declarations might be complex, long-winded, and thus
might in the end not be worth the effort.  The additional development
and maintenance cost of writing and maintaining the declarations might
not be worth whatever benefit it buys you in terms of preventing
unexpected exceptions.  In the case of non-template functions, the
declarations are usually simpler, and so the trade-off is different -
using exception specifications might be worthwhile in the simple case,
but might not be worthwhile in the case of templates.

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]






Author: jason@cygnus.com (Jason Merrill)
Date: 1995/11/15
Raw View
>>>>> Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:

> (It's a pity C++ doesn't have variable-argument macros like GNU C/C++ does -
> if it did, this could be made a bit more concise, e.g. just `THROW(X, Y)'
> rather than `EXCEPTIONS(throw(X, Y))'.)

Well, you could write `THROW((X, Y))':

#define THROW(ARGS) throw ARGS

Jason
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: dak <pierreba@poster.cae.ca>
Date: 1995/11/15
Raw View
In a previous artivle, Herb Sutter wrote:

>
> In article <9511120523.14310@mulga.cs.mu.OZ.AU>,
>    fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
> >herbs@interlog.com (Herb Sutter) writes:
> >>While we're on the subject of exception handling, is there any technical
> >>reason not to have an exception spec on every member function of every
> class?
> >
> >There is at least one technical reason - it won't work with template
> >classes.  Consider, for example, the member functions of the STL
> >collection classes.  What exception specification should they have?
>
> Hmm... good point, but while this is a good argument in the case of collection
> classes, is it necessarily true of all template classes?
>

Why shouldn't templates have exception specified ?  Saying that it depends on
the types used in the template instance seems gibberish to me: you could say
the same for any class that use any other class (eitehr publicly or in its
implementation).

The real problem is exception enforcement: a function without a throw clause
can throw any exception, but then again, maybe not. Thus the compiler cannot
enforce anything on such code. This is true for any class, and each time the
designer must decide if he wish to enforce a particular exception or let the
door open for anything to happen.

The fact that types used in template are unknown and may throw any exception
doesn't change that fact: either you put a catch expression on each usage of
the sub-type, or let the unexpected exception handler do the job or you don't
specify exceptions that can be thrown.
-
the biggest problem with C++ is its popularity.                    dak@cae.ca


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: herbs@interlog.com (Herb Sutter)
Date: 1995/11/12
Raw View
While we're on the subject of exception handling, is there any technical
reason not to have an exception spec on every member function of every class?
 Clearly there are the "tedium" and "dependencies (have to #include all
exception headers)" arguments, but what about performance, correctness, or
just stylistic drawbacks?

One I can think of is that it can make programs brittle by making it easy to
'miss a few' and get unexpected()s cropping up, but that could be mitigated by

Cline's proposal to set an unexpected handler that always rethrows (FAQ 271 of

his FAQ book):

   void myUnexpected() { cout << "unexpected exception!\n"; throw; }
   // or log it somewhere else, application's choice
   main() { set_unexpected(myUnexpected); ... }

I'm not sure I like this, since it can almost (not quite, but almost) be
viewed as defeating the purpose of using exception specs at all since
exceptions end up being successfully thrown regardless of what the exception
spec promised.  However, with a monolithic exception hierarchy you can get
pretty useful 'unexpected' message logging, as Cline points out later in the
same FAQ.


(Hey, Scott!  Here's an excellent one for your next book, if you're not at the

galley stage yet.)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Herb Sutter                 2228 Urwin, Ste 102         voice (416) 618-0184
Connected Object Solutions  Oakville ON Canada L6L 2T2    fax (905) 847-6019
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: smeyers@netcom.com (Scott Meyers)
Date: 1995/11/12
Raw View
In article <483e1r$kkd@steel.interlog.com> herbs@interlog.com (Herb Sutter) writes:
| While we're on the subject of exception handling, is there any technical
| reason not to have an exception spec on every member function of every class?
|  Clearly there are the "tedium" and "dependencies (have to #include all
| exception headers)" arguments, but what about performance, correctness, or
| just stylistic drawbacks?

There is a small performance penalty to be paid for each exception
specification, because they have to be checked at runtime to be sure
they're not violated.  This typically increases code size and decreases
code speed, though the cost of the feature varies from compiler to
compiler.

In addition, it's probably not practical to get an exception specification
for every function used in a program, because existing libraries typically
don't have them.  That being the case, it will be close to impossible to
guarantee they are never violated.

| (Hey, Scott!  Here's an excellent one for your next book, if you're not at the
|
| galley stage yet.)

"More Effective C++" does have some material on EH, including the above.
The book will be out in January.

Scott


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/11/12
Raw View
herbs@interlog.com (Herb Sutter) writes:

>While we're on the subject of exception handling, is there any technical
>reason not to have an exception spec on every member function of every class?


There is at least one technical reason - it won't work with template
classes.  Consider, for example, the member functions of the STL
collection classes.  What exception specification should they have?
It depends on what exceptions can be thrown by the Allocator class
and the collection element type.  C++'s exception specifications
don't provide a way to express that.

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/11/13
Raw View

herbs@interlog.com (Herb Sutter) writes:

>In article <smeyersDHwpw1.48n@netcom.com>,
>   smeyers@netcom.com (Scott Meyers) wrote:
>>There is a small performance penalty to be paid for each exception
>>specification, because they have to be checked at runtime to be sure
>>they're not violated.  This typically increases code size and decreases
>>code speed, though the cost of the feature varies from compiler to
>>compiler.
>
>Good point, but isn't the exception spec checked only when there actually is
>an exception? If so, then there should be no penalty in normal operation, to
>bastardise the old 'only pay for it if you use it' line.

An exception specification is pretty much equivalent to a `try ... catch'
block.  For example,

 void foo() throw (X, Y)
 {
  bar();
 }

is pretty much equivalent to

 void foo() {
  try {
   bar();
  }
  catch(const X &) {
   throw;
  }
  catch(const Y &) {
   throw;
  }
  catch(...) {
   unexpected();
  }
 }

Widespread use of exception specifications would definitely result in an
increase in code size, although it is difficult to say how significant this
would be.  (If anyone has any data on this, please post it!)
Whether or not it will have an impact on runtime speed depends on both
the compiler and the application.  Some compilers (such as Sun's C++
compiler and GNU C++, from what I have heard) implement exceptions in
such a way that a `try ... catch' block has only very minimal runtime
cost if an exception is thrown, but with other compilers (apparently
including Borland C++ and Microsoft C++, from what I have heard) there
is a definite run-time cost associated with a `try ...  catch' block,
and so there will almost certainly be a similar cost associated with
the use of exception specifications.

It might be a good idea to use a macro so that use of exception
specifications could be enabled or disabled via a command-line switch:

 #ifdef USE_EXCEPTION_SPECIFICATIONS
 #define EXCEPTIONS(x) x
 #else
 #define EXCEPTIONS(x) /* nothing */
 #endif

 void foo() EXCEPTIONS(throw(X, Y))
 {
  bar();
 }

This would enable you to easily measure the efficiency cost of
exception specifications.  You would want to keep them enabled for debugging
purposes, but if they turned out to be costly, and efficiency was important,
you could disable them for the production version.

(It's a pity C++ doesn't have variable-argument macros like GNU C/C++ does -
if it did, this could be made a bit more concise, e.g. just `THROW(X, Y)'
rather than `EXCEPTIONS(throw(X, Y))'.)

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ball@Eng.Sun.COM (Mike Ball)
Date: 1995/11/13
Raw View
In article 48n@netcom.com, smeyers@netcom.com (Scott Meyers) writes:
> There is a small performance penalty to be paid for each exception
> specification, because they have to be checked at runtime to be sure
> they're not violated.  This typically increases code size and decreases
> code speed, though the cost of the feature varies from compiler to
> compiler.

Well, not really.  If you can trust them (and you can now) a lot of them
can be eliminated at compile time.  Also, until the exception is thrown, the
cost can be reduced to an entry in a table that doesn't even need to be paged
in until the exception is thrown.  Of course, some archaic or otherwise
brain-damaged OS's don't support efficient exceptions, so they may have
problems. :-)

> In addition, it's probably not practical to get an exception specification
> for every function used in a program, because existing libraries typically
> don't have them.  That being the case, it will be close to impossible to
> guarantee they are never violated.

This is certainly true.  Also, how do you put them on template functions?
Then, what do you do about extern "C" functions?  You can put the exception
specification on them, but you pretty much have to just trust them.

-Mike Ball
SunSoft Developer Products.




---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]