From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Exception Specifications
Organization: Computer Science, University of Melbourne, Australia
Date: Wed, 30 Sep 1992 05:37:41 GMT

sdm@cs.brown.edu (Scott Meyers) writes:

>The more I think about it, the more I'm convinced that the uses for
>exception specifications are astonishingly restricted.  As I see it, you
>can't reliably put an exception specification on a function f if any of the
>following are true:
>
>    1.  A call to f might directly or indirectly lead to a call to g where
>        g lacks an exception specification.  A special case of this is
>        where g is a function written in another language, e.g., anything
>        in the standard C library.  Recall that functions without exception
>        specifications may throw anything.

What's wrong with
    extern "C" void g(void) throw ();
?

The grammar given in C++PL 2nd Ed. includes the non-terminal
"exception-specification", but this non-terminal is not refered to in the
rest of the grammar. Presumeably the production

    declarator : declarator ( argument-declaration-list ) cv-qualifier-list<opt>

should include exception-specification<opt> either before or after the
cv-qualifier-list<opt>, which would then mean that the above extern "C"
declaration is legal.

[By the way, which is it - before or after? Which of the following are legal:
	class X {
		void g() throw() const;		// before
		void f() const throw();		// after
	};
Or are both legal?]


>    2.  f is a template function.  In this case, f must be instantiated
>        using some unknown type T, and it is highly likey that f will
>        invoke some T-specific function (e.g. member function of class T).
>        However, there is no way to know what the exception specifications
>        are on the T-specific functions.
>
>    3.  f is a virtual function, because f may be redefined in a subclass
>        by some function f' that contains an incompatible exception
>        specification.  Recall that an exception specification is not part
>        of a function's type.
>
>The ARM refers to an exception specification as a "promise" (ARM 15.6.2c),
>but the above points make clear that this promise can't be given very
>often, or at least can't be relied upon very often.  Similarly, the
>discussion of why exception specifications are so lax is discussed in ARM
>15.5c.  The ARM also implies that special-purpose static analyzers would be
>required to do much of anything with exception specifications, especially
>in the presence of separate compilation.  (For example, if f contains an
>exception specification and calls virtual function g which also contains an
>exception specification, no warning can be issued if g is redefined by an
>incompatible g' in a derived class that is contained in a separate
>compilation unit.)

In C++PL 2nd Ed, BS says "An implementation may not reject an expression
simply because it _may_ throw an exception not specified in an exception-
specification of the function containing the expression; the handling
of violations of an exception-specification is done at run-time."

However this does NOT mean that the implementation may not give WARNINGS
in such cases. In particular I would not be satisfied with a compiler that
did not give me a warning any time that I 

	- call a function whose exception-specification is not a subset of
          the calling function's exception-specification;

	- redefine a virtual function with one whose exception-specification is
	  not a subset of the exception-specification of the base class's
	  function;

	- instantiate a template in such a manner as to cause either of the
	  above.

----------------------------------------------------------------------

If an exception is raised in a destructor while unwinding the stack
from a previous exception, then the function terminate() is called.

This means that in general, destructors should NEVER raise any exceptions.
I want to be able to put that exception specification on all my destructors.

	~X::X() throw() {...}

Furthermore, I want the compiler to check that at compile time, not at run-time.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
Newsgroups: comp.std.c++