Topic: Function Throw Specifications


Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/05/17
Raw View
Alexis Layton <alex@InConcert.COM> writes:

> int foo() throw (FooException, ...);
>
> This construct would mean there is no constraint on what exceptions can
> be thrown by foo(), but it will throw FooException from time to time.

So it says nothing... or it says something you can as well
say in a comment.

A language feature, as opposed to a comment, is useful if
the compiler can:
(1) check it
(2) optimise based on it

Here (1) doesn't seem to be very interresting, and (2) not
possible at all.

What I'd like is a warning which tells me all the places
where exception specifications can't be proved statically.
Possibly ignoring all logic_errors (that is, adding a
throw (logic_errors) in all exceptions specifications).

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Alexis Layton <alex@InConcert.COM>
Date: 1998/05/06
Raw View
Steve Clamage wrote:

> But no provision has been made to catch any other exception that
> foo might throw. I don't see an advantage in the compiler singling
> out one (or a set) of the exceptions that could possibly be
> thrown. In any event the compiler can warn about possible uncaught
> exceptions even if foo has no throw specification at all.

I think the distinction I was making was between functions that use
exceptions as an alternate return mechanism vs. the more "unexpected"
type of exception such as running out of various resources.  This was
the case with a parsing function that returned a parse object, or threw
a parse error object.  In most cases, alternate return type exceptions ought
to be caught at the place of calling, as opposed to higher up the stack,
unlike resource exhaustion exceptions, that are often caught at a higher
level.

--
Alexis Layton                           InConcert Incorporated,
Sr. Software Engineer                   A Xerox New Enterprises Company
alex@InConcert.COM                      Four Cambridge Center
+1 617 499-4443                         Cambridge, MA  02142-1494
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Alexis Layton <alex@InConcert.COM>
Date: 1998/05/01
Raw View
After using exceptions for a while, it seems to me that in most
cases using throw specifications is more trouble than it's worth.

However, I find I wish I were able to "document" that a particular
function routinely throws a specific exception without constraining
the throwing of exceptions that may have occurred in its own processing.

I am now at the point that I wish the committee had allowed
the following construct:

class FooException {
public:
 /* whatever */
};

int foo() throw (FooException, ...);

This construct would mean there is no constraint on what exceptions can
be thrown by foo(), but it will throw FooException from time to time.

I forsee this functioning as primarily interface documentation, but
it is possible that very helpful compiler might notice

void bar() throw ()
{
 /* ... */
 int x = foo();
 /* ... */
}

and warn the user that no provision has been made to catch FooException
should it occur.  (Of course, as discussed previously, that might
still be too helpful if the caller has taken pains to ensure that
it doesn't happen.)

So, now I'm waiting for all you smart people to tell me what
a horrible and ridiculous idea this is....

--
Alexis Layton    InConcert Incorporated,
Sr. Software Engineer   A Xerox New Enterprises Company
alex@InConcert.COM   Four Cambridge Center
+1 617 499-4443    Cambridge, MA  02142-1494
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: loewis@informatik.hu-berlin.de (Martin v. Loewis)
Date: 1998/05/01
Raw View
Alexis Layton <alex@InConcert.COM> writes:

> So, now I'm waiting for all you smart people to tell me what
> a horrible and ridiculous idea this is....

Documenting things is not a horrible idea per se. However, there are
already mechanisms in the language for inserting documentation into
the program, namely comments. So I see no need for introducing new
syntax just for documentation.

[...]
> int foo() throw (FooException, ...);
[...]
> I forsee this functioning as primarily interface documentation, but
> it is possible that very helpful compiler might notice
>
> void bar() throw ()
> {
>  /* ... */
>  int x = foo();
>  /* ... */
> }
>
> and warn the user that no provision has been made to catch FooException
> should it occur.

If you write

int foo();

the compiler could still warn that you are calling a function which
might throw exceptions, without putting them into a try-catch-block.
It would be then up to you to find out whether this can really happen,
and modify the declaration of foo appropriately. Or you could just
ignore the warning.

Regards,
Martin


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/05/02
Raw View
Alexis Layton <alex@InConcert.COM> wrote:
: After using exceptions for a while, it seems to me that in most
: cases using throw specifications is more trouble than it's worth.

: However, I find I wish I were able to "document" that a particular
: function routinely throws a specific exception without constraining
: the throwing of exceptions that may have occurred in its own processing.

When an exception, not listed in the exception specification, is
thrown, the unexpected() is called. You can substitute your own
function for unexpected(). In your own my_unexpected(), you can
rethrow the current exception with no-argument ``throw''. This
way, you will propagate any exception out.

Hope this helps.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: rphorvic@gloria.cord.edu (Robert Horvick)
Date: 1998/05/02
Raw View
Alexis Layton (alex@InConcert.COM) wrote:
: After using exceptions for a while, it seems to me that in most
: cases using throw specifications is more trouble than it's worth.
: I am now at the point that I wish the committee had allowed
: the following construct:

: class FooException {
[snip]
: int foo() throw (FooException, ...);

Alexis,

While I find my solution to this to be a hack, and perhaps even displaying
a flaw in MSVC++ and g++ 2.7.2.2 (Solaris 2.4) but I have found that you
can have a exception-specification of

void Func() throw(void, void*)

which allows you to throw any type you should want.  I find this ability a
little disturbing since void is not a type which objects can be
instantiated from (standard guru's, is this a violation of ISO C++?) but,
never-the-less, it works.

Here is some code to demonstrate this:
--- begin: except.cpp
#include <iostream>

class Exception
{
public:
 Exception() {}
 ~Exception() {}
};

void Func1() throw(int, void, void*)
{
 Exception e;
 throw (e);
}

int main()
{
 try {
  Func1();
 }
 catch( Exception e ) {
  std::cout << "caught Exception" << std::endl;
 }
 return 0;
}
--- end: except.cpp

This does not, as you request, solve the problem of compile time reporting
of potentially missed exception handling, and in fact, is, for all
practical purposes, the same as a throw() exception-specification, but you
can see that the possiblilty for advertising the major exceptions thrown
is available.  I advertise an int, but never throw it.

I would be most interested in hearing how this usage of void in
exception-specifications is thought of by the folks who make this all
possible.

Robert Horvick

     +-----------------------+----------------------------------------+
     |   Robert P. Horvick   | http://www.cord.edu/homepages/rphorvic |
     | Great Plains Software |   Concordia College, Computer Science  |
     |   rhorvick@acm.org    |        calloc(1, sizeof(geek));        |
     +-----------------------+----------------------------------------+
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/05/02
Raw View
In article 55671489@InConcert.COM, Alexis Layton <alex@InConcert.COM> writes:
>
>I am now at the point that I wish the committee had allowed
>the following construct:
>
>class FooException {
>public:
> /* whatever */
>};
>
>int foo() throw (FooException, ...);
>
>This construct would mean there is no constraint on what exceptions can
>be thrown by foo(), but it will throw FooException from time to time.

Such a proposal was considered by the C++ Committee a few years ago.
The conclusion was that it served no useful purpose, since
omitting a throw specification means exactly the same thing.

>I forsee this functioning as primarily interface documentation, but
>it is possible that very helpful compiler might notice
>
>void bar() throw ()
>{
> /* ... */
> int x = foo();
> /* ... */
>}
>
>and warn the user that no provision has been made to catch FooException
>should it occur.

But no provision has been made to catch any other exception that
foo might throw. I don't see an advantage in the compiler singling
out one (or a set) of the exceptions that could possibly be
thrown. In any event the compiler can warn about possible uncaught
exceptions even if foo has no throw specification at all.

---
Steve Clamage, stephen.clamage@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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/05/02
Raw View
Alexis Layton wrote:
>
> After using exceptions for a while, it seems to me that in most
> cases using throw specifications is more trouble than it's worth.

I agree. At least in the Borland compiler, they always add code, and the
compiler makes no effort to optimize the callers of functions that have
exception specs. Someday this may not be the case, but for now, I eschew
them.

--

Ciao,
Paul
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: abell8920@mindspring.com (Andrew Bell)
Date: 1998/05/02
Raw View
On 02 May 98 02:54:39 GMT, Oleg Zabluda <zabluda@math.psu.edu> wrote:

>Alexis Layton <alex@InConcert.COM> wrote:
>: After using exceptions for a while, it seems to me that in most
>: cases using throw specifications is more trouble than it's worth.

I'm afraid I have to agree with you.  I try to document the exceptions
that are thrown with commented versions of the specifiers, but
otherwise I don't use them.

>When an exception, not listed in the exception specification, is
>thrown, the unexpected() is called. You can substitute your own
>function for unexpected(). In your own my_unexpected(), you can
>rethrow the current exception with no-argument ``throw''. This
>way, you will propagate any exception out.

This doesn't work.  (Or if it does, your compiler is not following the
standard as of December '96.)

15.4:

9: The function unexpected() may throw an exception that will satisfy
the exception-specification for which it was invoked, and in this case
the search  for  another handler will continue at the call of the
function with this exception-specification (see _except.unexpected_),
or it may call terminate().

and 15.5.2:

2 The unexpected() function shall not return, but it can throw  (or
re-throw) an exception.  If it throws a new exception which is allowed
by the exception specification which previously was  violated,  then
the search  for  another handler will continue at the call of the
function whose exception specification was violated.  If it throws or
rethrows an  exception that the exception-specification does not allow
then the following happens: if the exception-specification does not
include the class  std::bad_exception (_lib.bad.exception_) then the
function terminate() is called, otherwise the thrown exception is
replaced  by  an implementation-defined  object  of the type
std::bad_exception and the search for another handler will continue at
the call of  the  function whose exception-specification was violated.


So rethrowing the exception that caused unexpected to be called will
not satisfy the exception-specification.  In particular, if you have a
throw () specifier, calling terminate() from unexpected() is your only
option.

--Andrew Bell
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/05/02
Raw View
Alexis Layton <alex@InConcert.COM> writes:

>I am now at the point that I wish the committee had allowed
>the following construct:
>
>class FooException {
>public:
> /* whatever */
>};
>
>int foo() throw (FooException, ...);
>
>This construct would mean there is no constraint on what exceptions can
>be thrown by foo(), but it will throw FooException from time to time.

If you derive all your exception classes from std::exception,
then writing

 int foo() throw(FooException, std::exception);

would achieve what you want.

--
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/05/02
Raw View
rphorvic@gloria.cord.edu (Robert Horvick) writes:

>While I find my solution to this to be a hack, and perhaps even displaying
>a flaw in MSVC++ and g++ 2.7.2.2 (Solaris 2.4) but I have found that you
>can have a exception-specification of

>void Func() throw(void, void*)

>which allows you to throw any type you should want.

The C++ draft standard requires the types in a throw-specification
to be complete types. By definition, type void is not a complete
type, so the specification is not valid. Even if it were valid,
an ommitted throw-specification allows the function to throw
any exception, so you don't need the hack.

---
Steve Clamage, stephen.clamage@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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]