Thread View: comp.std.c++
3 messages
3 total messages
Started by Paul D. DeRocco
Sun, 18 Feb 1996 02:14
Conflicting purposes of exception spec
Author: Paul D. DeRocco
Date: Sun, 18 Feb 1996 02:14
Date: Sun, 18 Feb 1996 02:14
68 lines
4105 bytes
4105 bytes
It occurs to me that exception specifications, at least empty ones,
have two possible purposes, and that they conflict in a sense. One is
to inform the compiler that exceptions actually won't occur, and the
other is to trap any exceptions that the programmer didn't think would
occur but wasn't sure about. The former is in the category of an
optimization hint, like the "register" keyword, while the latter is a
debugging aid, like an assertion.
An empty exception specifier can be a significant aid to optimizing
the caller of a function. If the caller has a local object whose class
has a destructor, it needs to set up an exception context to guarantee
that the destructor is called even if an exception is thrown. If the
body of the function contains no function calls and no throw
statements, then it can optimize out the exception context. In theory,
it can also optimize it out when there are function calls, as long as
they all have throw() in their declarations.
So consider a simple function that I _know_ won't throw an exception:
int sumsq(int a, int b) { return a * a + b * b; }
Do I put a throw() clause on it or not? If the compiler uses throw()
only as an optimization hint to the caller, then I most definitely
_do_ want to use it. If, on the other hand, the compiler treats
throw() as a command to add code to prevent any exceptions from
propagating out of the function, then I most definitely _don't_ want
to use it. If I guess wrong about the interpretation, I've bought
myself nothing, and cost myself something. And unless it's spelled out
in the language definition, I can't make _either_ choice without
knowing that it won't ever be compiled with a compiler that was
designed with the opposite choice in mind.
When non-empty exception specifiers are present, things are a bit
simpler, because such a construct isn't particularly useful as an
optimization hint. When compiling the caller of such a function, an
exception context is needed to guarantee destructor cleanup if _any_
exception can be thrown, even if it is a limited set. About the only
situation where a non-empty exception specifier can aid optimization
is if a try block contains only calls to functions that can throw
exceptions that aren't mentioned in the catch clauses. But in real
life, one doesn't try to catch exceptions unless they can actually
occur.
This suggests that the use of an exception specifier as an assertion
is the "correct" interpretation. But the use of an empty specifier as
an optimization hint is potentially useful, so I propose an
alternative. Let throw() intercept all exceptions and turn them into
unexpected(), but use throw(void) to mean that the function really
doesn't throw any exceptions.
So what should happen if a function declared with throw(void) actually
throws an exception? Consider it "ill-formed", and let it do whatever
it likes, including unwinding the stack and missing destructors. This
would certainly be a bug, but there are entire categories of functions
that the programmer can be assured will never throw exceptions,
including just about the entire C string library.
--
Ciao,
Paul D. DeRocco
[ To submit articles: Try just posting with your newsreader. 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
]
Re: Conflicting purposes of exception spec
Author: Steve Clamage
Date: Sun, 18 Feb 1996 17:07
Date: Sun, 18 Feb 1996 17:07
50 lines
3079 bytes
3079 bytes
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>So consider a simple function that I _know_ won't throw an exception:
> int sumsq(int a, int b) { return a * a + b * b; }
>Do I put a throw() clause on it or not? If the compiler uses throw()
>only as an optimization hint to the caller, then I most definitely
>_do_ want to use it. If, on the other hand, the compiler treats
>throw() as a command to add code to prevent any exceptions from
>propagating out of the function, then I most definitely _don't_ want
>to use it. If I guess wrong about the interpretation, I've bought
>myself nothing, and cost myself something. And unless it's spelled out
>in the language definition, I can't make _either_ choice without
>knowing that it won't ever be compiled with a compiler that was
>designed with the opposite choice in mind.
You probably don't need to worry about bad effects of adding empty
exception-specifications.
If sumsq doesn't have an exception-specification, the compiler must
assume that any call to sumsq could result in any exception being
thrown. If sumsq has a throw() clause, the compiler can assume that
no exceptions will escape from sumsq, and perhaps can avoid adding
exception-handling code to the calling location. At the call
site, there are no disadvantages to sumsq's empty exception-spec,
and there are potential advantages, as you noted in your article.
(A function that calls sumsq might also call other functions that
can throw exceptions, in which case you probably get no benefit at
that call site.)
If a function has an empty exception-spec, the compiler must in
general add scaffolding to the function to ensure that any exceptions
occurring in the function do not escape. In the case of sumsq, the
compiler may be able to determine that no exception is possible,
and not generate the extra code. If the extra code is generated,
on most implementations it does not add to the run time of the
function. Typically none of the extra code is executed unless an
exception actually occurs and would otherwise escape from the function.
--
Steve Clamage, stephen.clamage@eng.sun.com
[ To submit articles: Try just posting with your newsreader. 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
]
Re: Conflicting purposes of exception spec
Author: Paul D. DeRocco
Date: Mon, 19 Feb 1996 16:52
Date: Mon, 19 Feb 1996 16:52
48 lines
2990 bytes
2990 bytes
Steve Clamage wrote: > If sumsq has a throw() clause, the compiler can assume that > no exceptions will escape from sumsq, and perhaps can avoid adding > exception-handling code to the calling location. At the call > site, there are no disadvantages to sumsq's empty exception-spec, > and there are potential advantages, as you noted in your article. The Borland compiler makes no attempt at optimizition of the caller in this case. > If a function has an empty exception-spec, the compiler must in > general add scaffolding to the function to ensure that any exceptions > occurring in the function do not escape. In the case of sumsq, the > compiler may be able to determine that no exception is possible, > and not generate the extra code. If the extra code is generated, > on most implementations it does not add to the run time of the > function. Typically none of the extra code is executed unless an > exception actually occurs and would otherwise escape from the > function. The Borland compiler makes no attempt to deduce whether it really needs this code, and adds it no matter what. It amounts to a couple of calls to helper functions which don't amount to that much code, but too much, in my view, for simple functions like sumsq (or, say, C string handling functions like strlen). It was my experience with the Borland compiler that led me to these thoughts. I tried adding throw() to all my diddling little utility functions, in the hopes that it would simplify some of the calling code, and was surprised to find that it didn't do that, but instead made the functions more complicated. I then decided to junk the throw() specifiers. Then, however, it occurred to me that with a different compiler, junking the throw() specifiers could be the exact wrong thing to do. Hence, my desire for throw(void) to be explicitly defined as an optimization hint. -- Ciao, Paul D. DeRocco [ To submit articles: Try just posting with your newsreader. 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 ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads