Topic: Exception specifications


Author: apm35@student.open.ac.uk (apm)
Date: Fri, 30 Nov 2001 19:27:57 GMT
Raw View
Adam Peterson <ahp6@email.byu.edu> wrote in message news:<9u40sd$uq5$1@acs2.byu.edu>...
> <snip>
>
> Here's what I would like to see:
>
> A compiler is obviously capable of determining which exceptions may be
> thrown by which functions.  Java's compiler can prove this;

Please look at my proposal in
http:///wwww.andrewmarlow.co.uk/publications.html where I describe a
facility for adding strong ES checking to C++. It's main weakness is
that it does not address the issue of templates but I am working on
MARK II as we speak. I also compare it to what we have in Java. You
also might like to follow the discussion on comp.lang.c++.moderated.
:-)

-Andrew M.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: apm35@student.open.ac.uk (apm)
Date: Tue, 27 Nov 2001 18:28:37 GMT
Raw View
"Roger Orr" <rogero@howzatt.demon.co.uk> wrote in message news:<1006385436.3004.0.nnrp-08.9e98aa01@news.demon.co.uk>...
>
> PS It is (off topic but) interesting to note that Java is having similar
> debates about what the best style is for writing exception specs and whether
> checked exceptions, as they are known, are a *good thing* or not.

There are even similar discussions in the Eiffel conference. Basically
there seems to be little agreement about exactly what exceptions
should be used for. IMHO Java is using them where error codes would be
more useful. Eiffel virtually never uses them, and C++ is somewhere in
the middle. I posted a proposal in clcm about tightening up the ES in
C++ but have now changed my mind and withdrawn the proposal. It is
still available on-line for historical interest, at
http://www.andrewmarlow.co.uk/publications.html.

I have changed my mind because after some clcm discussion I asked
myself a more fundamental question: 'Given that exceptions are what
happens when the contract is broken, do the exceptions that might be
thrown form part of the contract itself?'. In my original proposal I
presupposed that the answer to this was 'yes'. I have now changed my
mind, based on certain things I have found in the C++ standard about
ESs and based on what I have read in OOSC(II) about DbC and Eiffel
exceptions.

Regards,

Andrew M.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: apm35@student.open.ac.uk (apm)
Date: Tue, 27 Nov 2001 18:47:09 GMT
Raw View
"John Brown" <nospam@nospam.com> wrote in message news:<mktM7.21196$2i.9412239@news3.rdc1.on.home.com>...
> > So in actual practice I tend to add a _commented out_ throw spec to
>  express
> > my intent ... like this:-
> >
> > 1b) void foo(); // throw()
> > 2b) void foo(); // throw( database_exception )
> > 3b) void foo();
> >
> > Please feel free to comment on this :)

Thank you, I will :-)

I have seen this done on projects before and there is a danger:
developers not in the know do not know why it is commented out and
turn the comment into a real ES.

Regards,

Andrew M.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Adam Peterson <ahp6@email.byu.edu>
Date: Thu, 29 Nov 2001 00:54:25 GMT
Raw View
<snip>

Here's what I would like to see:

A compiler is obviously capable of determining which exceptions may be
thrown by which functions.  Java's compiler can prove this; when you mess up
the exception spec., it tells you where and why.  So, why not have the
compiler determine which exceptions can be thrown from main(), and the
call-stack for each (barring recursion)?  Those are the only exceptions I
really feel I need to be sure to handle if I haven't already handled them
elsewhere.  With such a message, I can look at the expected call trace and
find the best place to insert a handler.

Or, perhaps, we could have the compiler determine when any exception
specification might be violated, and notify the programmer at compile or
perhaps link time.  This would be more general, as we could then say that
main is declared with throw(), or failing that, a consciencious programmer
could simply have 'int main(...)' call 'int mymain(...) throw()' and we'd
have the same checking.  The only things that couldn't be checked is
constructors (and possibly destructors) of global objects throwing
exceptions, but that may be addressable as well by something similar.

I wouldn't expect these messages to the programmer to be fatal errors; I
would expect at worst a warning which probably would have to be explicitly
enabled with a flag or something if desired.  Unfortunately, I fear that
this places my proposal solidly in the Quality of Implementation bin, but I
can still fantasize.




---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "John Brown" <nospam@nospam.com>
Date: Wed, 21 Nov 2001 14:09:31 CST
Raw View
I'm interested in opinions on the use of exception specifications on virtual
functions. The rules say that any exceptions thrown by an overridden
function must be as restrictive as the base class (exception) specification
.. However, since you can't always know ahead of time what exception a
derived function might want to throw, does it make sense to provide an
exception specification at all on the base class function. If you do and
someone later overrides it with some *less* restrictive exception, then you
not only have to change the base class exception specification, but you're
now faced with tracking down all code that was originally based on the old
specification (adding a new catch clause if required and possibly having to
re-evaluate the surrounding logic). This can be troublesome and might not
even be possible in all cases, especially where the code has been
distributed for 3rd-party use. It therefore seems to me that it's far less
clean but safer to omit the exception specification entirely in these cases
(since the absence of any specification means any exception is allowed). Any
comments?

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 21 Nov 2001 21:55:44 GMT
Raw View
In article <HCTK7.226179$YL3.71167154@news3.rdc1.on.home.com>, John
Brown <nospam@nospam.com> writes
>I'm interested in opinions on the use of exception specifications on virtual
>functions. The rules say that any exceptions thrown by an overridden
>function must be as restrictive as the base class (exception) specification
>.. However, since you can't always know ahead of time what exception a
>derived function might want to throw, does it make sense to provide an
>exception specification at all on the base class function. If you do and
>someone later overrides it with some *less* restrictive exception, then you
>not only have to change the base class exception specification, but you're
>now faced with tracking down all code that was originally based on the old
>specification (adding a new catch clause if required and possibly having to
>re-evaluate the surrounding logic). This can be troublesome and might not
>even be possible in all cases, especially where the code has been
>distributed for 3rd-party use. It therefore seems to me that it's far less
>clean but safer to omit the exception specification entirely in these cases
>(since the absence of any specification means any exception is allowed). Any
>comments?

Yes, exception specifications do not work very well. However in this
case, I cannot see the alternatives doing more than making a poor design
even worse.


--
Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Roger Orr" <rogero@howzatt.demon.co.uk>
Date: Sat, 24 Nov 2001 01:53:47 GMT
Raw View
John Brown wrote in message ...
>I'm interested in opinions on the use of exception specifications on
virtual
>functions.
[snip]
Yes, so am I :)

In my mind there are (at least) three different design intentions for a
virtual function 'foo()':

1) I don't want overrides of this method to ever throw.

An obvious example is the destructor.
Code using foo() is written assuming the method can't throw.
If overrides of foo() throw exceptions my code can no longer be guaranteed
to be exception safe at all.

2) Overrides of foo() will throw one specific class (or hierarchy) of
exception to indicate errors.

I'll be writing code using the base class and try ... catch with that
_specific_ exception class in mind.
If you throw any other exceptions my code will not catch them (although it
should still be exception safe*).

3) I don't care what exceptions are thrown.

All code written to use foo() will assume _any_ exception might be thrown
and has to be exception safe in such cases.

[* - whether basic, strong, or some other guarantee isn't discussed here]

At first sight this means I should write, for example:-

1a) void foo() throw();
2a) void foo() throw( database_exception );
3a) void foo();

Unfortunately ... the C++ exception specification means I don't get what I
want.
In particular the fact that nothing (in any compiler I've ever used) checks
whether my methods _actually_ comply with their throw spec means that it is
all too easy for unexpected exceptions to unconditionally abort my program.

So in actual practice I tend to add a _commented out_ throw spec to express
my intent ... like this:-

1b) void foo(); // throw()
2b) void foo(); // throw( database_exception )
3b) void foo();

Please feel free to comment on this :)

Regards,
Roger Orr

PS It is (off topic but) interesting to note that Java is having similar
debates about what the best style is for writing exception specs and whether
checked exceptions, as they are known, are a *good thing* or not.
--
MVP in C++ at www.brainbench.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://www.research.att.com/~austern/csc/faq.html                ]





Author: apm35@student.open.ac.uk (apm)
Date: Sat, 24 Nov 2001 01:54:28 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote in message news:<lSwjRIV+BC$7EwoI@robinton.ntlworld.com>...
> Yes, exception specifications do not work very well. However in this
> case, I cannot see the alternatives doing more than making a poor design
> even worse.
> --
> Francis Glassborow

In that case please look at my proposal in comp.lang.c++.moderated.
Here's what I said at the start of the thread:

Here's a concise summary of my proposal for stricter
exceptionspecifications:
By using the word 'onlythrow' instead of 'throw', exception
specifications are subject to static checking and single level
propagation. Violations of an onlythrow list are a compilation error.
Such errors only apply to functions that have an onlythrow list.
Functions that do not have an onlythrow list that call routines that
do are not affected. Functions with an onlythrow list may not call
functions with a throw list since such functions might call
unexpected. A compiler that implements onlythrow must ship with a
standard C++ library that uses onlythrow rather than throw in its
exception specifications.

I have a longer document that describes the proposal in detail but I
thought I would see what interest there is first.

Regards,

Andrew M.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "John Brown" <nospam@nospam.com>
Date: Sat, 24 Nov 2001 01:54:41 GMT
Raw View
> Yes, exception specifications do not work very well. However in this
> case, I cannot see the alternatives doing more than making a poor design
> even worse.

Thanks for the feedback. Poor design in this case isn't the fault of the
developer however. What is one supposed to do if you write a virtual
function that throws, say, "MyException" or perhaps no exceptions at all. If
you document either using an exception specification then it leads to the
problem I discussed. Not documenting it however makes for poor design as you
suggested. The programmer may have no choice but to opt for the latter.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "David Abrahams" <david.abrahams@rcn.com>
Date: Sat, 24 Nov 2001 21:06:53 GMT
Raw View
"John Brown" <nospam@nospam.com> wrote in message
news:NdaL7.1034$2i.1083577@news3.rdc1.on.home.com...

> Thanks for the feedback. Poor design in this case isn't the fault of the
> developer however. What is one supposed to do if you write a virtual
> function that throws, say, "MyException" or perhaps no exceptions at all.
If
> you document either using an exception specification then it leads to the
> problem I discussed. Not documenting it however makes for poor design as
you
> suggested. The programmer may have no choice but to opt for the latter.

C++ has at least two wonderful (well, perfectly adequate) mechanisms for
documenting code: they are spelled // and /*...*/.

Maybe "exception specification" was poorly named, since "specification" may
lead people to think that it's supposed to be used for documentation.

-Dave



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 24 Nov 2001 21:14:50 CST
Raw View
In article <d1a33011.0111220244.74896013@posting.google.com>, apm
<apm35@student.open.ac.uk> writes
>In that case please look at my proposal in comp.lang.c++.moderated.
>Here's what I said at the start of the thread:

But exactly how does your proposal fix ES and templates. That is the
crunch, fixing static checking is easy.

--
Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 26 Nov 2001 01:57:37 GMT
Raw View
David Abrahams wrote:
...
> C++ has at least two wonderful (well, perfectly adequate) mechanisms for
> documenting code: they are spelled // and /*...*/.

Yes, and that same approach could also be used, for instance, to
document the argument types required by functions. Despite the
availability of comments, it was a definite improvement when function
prototypes were first introduced. There's value in documentation that is
actually enforced as a feature of the language.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "David Abrahams" <david.abrahams@rcn.com>
Date: Mon, 26 Nov 2001 05:30:51 GMT
Raw View
"James Kuyper Jr." <kuyper@wizard.net> wrote in message
news:3C007D0F.ACDEDE77@wizard.net...
> David Abrahams wrote:
> ...
> > C++ has at least two wonderful (well, perfectly adequate) mechanisms for
> > documenting code: they are spelled // and /*...*/.
>
> Yes, and that same approach could also be used, for instance, to
> document the argument types required by functions. Despite the
> availability of comments, it was a definite improvement when function
> prototypes were first introduced. There's value in documentation that is
> actually enforced as a feature of the language.


You'll get no argument from me!
On the other hand, restoring the context of the original post:



"John Brown" <nospam@nospam.com> wrote in message
news:NdaL7.1034$2i.1083577@news3.rdc1.on.home.com...

> Thanks for the feedback. Poor design in this case isn't the fault of the
> developer however. What is one supposed to do if you write a virtual
> function that throws, say, "MyException" or perhaps no exceptions at all.
If
> you document either using an exception specification then it leads to the
> problem I discussed. Not documenting it however makes for poor design as
you
> suggested. The programmer may have no choice but to opt for the latter.



The O.P. seemed to take for granted that if you can't document the
exceptions thrown by a function in enforced constructs, you can't document
them at all.


And on the /other/ other hand, there's at least some indication that
enforced exception specifications might actually cost more than they buy
you. Restricting the types of errors that can be reported doesn't do much to
help with program reliability IMO, and users of Java often report that
working around the enforcement amounts to busywork for little benefit.

The analogy with argument type checking isn't really a strong one. Remember
that (static) argument type checking prevents crashes, because without it
you are liable to apply an operation meant for objects of type A to an
object of type B. Conversely, exception types are always checked dynamically
by the catch mechanism, so that (barring casts which are dangerous in any
case), you can't mis-apply operations to exception objects.


-Dave


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "John Brown" <nospam@nospam.com>
Date: Mon, 26 Nov 2001 19:36:56 GMT
Raw View
> So in actual practice I tend to add a _commented out_ throw spec to
express
> my intent ... like this:-
>
> 1b) void foo(); // throw()
> 2b) void foo(); // throw( database_exception )
> 3b) void foo();
>
> Please feel free to comment on this :)

Yes, as others have also suggested. However, it tells users of a function
that it can throw any exception even though that's not true in actuality.
The comments tell the true story which may be useful to know but you still
have to catch (...) even if the function is never overridden (or is
overridden by a function throwing something as restrictive as your comments
have documented). So client code has to catch (...) and process this even
though it may never get called for the entire life of the app. It's simply a
protection mechanism against the possibility that some derived function
*may* need to thrown something less restrictive one day. Or, as you
correctly pointed out, it also safeguards against unexpected exceptions
whether the function is overridden or not. In reality that may never happen
however and in many applications it's all but guaranteed. In these cases all
(...) handlers then exist for reassurance purposes only. That's great for
apps that absolutely must be bullet proof (medical, etc.) but I'm interested
in the theory behind all this. It seems to me that exception specifications
need to be re-thought for these circumstances. They do more than just
document after all, they assist compilers in checking for unexpected
exceptions (whether any current compiler does so or not) and may result in
more streamlined and efficient code depending on the platform. Another post
already proposed some alternative syntax but I didn't examine it in detail.
Until it's adopted however it doesn't help right now.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]