Topic: C++ exception handling model


Author: rb@cc.ic.ac.uk (Robin Becker)
Date: 8 Nov 91 14:18:42 GMT
Raw View
A recent issue of .EXE magazine contains an article on C++ exceptions
(I can't remember the author's name apologies :-) ) and pointed out
the following problems.
 1) C++ exception handlers are defined by a type which can
  lead to problems with libraries. I.e. we both want
  to use the same type.
 2) C++ has problems when one doesn't want to use the
  termination model for the handler, i.e. you can't
  resume the processing at the original exception point.

the article claims that the ADA exception mechanism overcomes problem 1
by delaying the exception handling definitions till link time (I'm not
an ADA person so I'm not very clear on this, but I seem to remember
that package definitions can export the exceptions which they raise).
As for problem 2 it seems that the commonly used C (signal/setjmp/longjmp)
methodology overcomes this but is not compatible with C++.

Since exceptions are semantically quite difficult and apparently not yet
completely standardised I would oppose a mechanism which forbids
resumption after some error correction.  I have in mind processing of
high priority stuff when something minor occurs i.e. we're trying to
shut down the nuclear reactor and the fuse on the outside lighting
blows, it seems we should safely be able to ignore the latter.
Any comments?  Robin




Author: root@mole-end (0000-Admin(0000))
Date: 10 Nov 91 05:53:29 GMT
Raw View
In article <1991Nov8.141843.6034@cc.ic.ac.uk>, rb@cc.ic.ac.uk (Robin Becker) writes:

> A recent issue of .EXE magazine contains an article on C++ exceptions
> (I can't remember the author's name apologies :-) ) and pointed out
> the following problems.
>  1) C++ exception handlers are defined by a type which can
>   lead to problems with libraries. I.e. we both want
>   to use the same type.

Eh?  Yes, we do have to share a global namespace.  Exceptions don't
create this problem.  Or have you something else in mind?

>  2) C++ has problems when one doesn't want to use the
>   termination model for the handler, i.e. you can't
>   resume the processing at the original exception point.

> that package definitions can export the exceptions which they raise).
> As for problem 2 it seems that the commonly used C (signal/setjmp/longjmp)
> methodology overcomes this but is not compatible with C++.

Don't confuse an asynchronous event (signal) with the means of handling
an event (exception or setjmp/longjmp).

> Since exceptions are semantically quite difficult and apparently not yet
> completely standardised I would oppose a mechanism which forbids
> resumption after some error correction.  I have in mind processing of
> high priority stuff when something minor occurs i.e. we're trying to
> shut down the nuclear reactor and the fuse on the outside lighting
> blows, it seems we should safely be able to ignore the latter.
> Any comments?  Robin

Well, yes.  For a variety of reasons, resumption isn't going to be
supported this time around, although it looks like some minor changes
were made so that it could be added in the future.

More than that, though ... are you sure that exceptions are what you
WANT to handle this case?  An exception is not JUST an `ON-Condition',
it is a means of transferring control under that condition to some
ancestor function which has the `context' to handle the situation.  That
doesn't sound like this case at all, which is a matter of prioritized
events and processes.  In this case you don't even want to raise the
exception, much less return control somewhere else--because that somewhere
else won't know (won't have the context) to determine that it can't
bug out.
--

 (This man's opinions are his own.)
 From mole-end    Mark Terribile




Author: rmartin@erde.Rational.COM (Bob Martin)
Date: 11 Nov 91 17:46:48 GMT
Raw View
rb@cc.ic.ac.uk (Robin Becker) writes:

>A recent issue of .EXE magazine contains an article on C++ exceptions
>(I can't remember the author's name apologies :-) ) and pointed out
>the following problems.
> 1) C++ exception handlers are defined by a type which can
>  lead to problems with libraries. I.e. we both want
>  to use the same type.

This is a problem with C++ Classes in general.  There is no way to
hide a cohesive set of class names within an isolated context.
(nested classes might seem like a way to do this, but they can't
really be used for large scale groupings.)

This inability to hide a group of classes means that we are exposed to
name clashes whenver we integrate someone elses software with our own.
This makes it hard to use two or three different vendor's products
toghether...

I view this as a severe problem which needs to be solved before the
language can be viewed as complete...

> 2) C++ has problems when one doesn't want to use the
>  termination model for the handler, i.e. you can't
>  resume the processing at the original exception point.

I suppose that's true.  One cant simply return from a catch and start
executing right below the throw.  I'm not sure allowing that would be
such a good idea anyway.

But one can easily implement "try-again" models:

void f()
{
  int keepTrying = 1;
  while (keepTrying)
  {
    try
    {
      /* do some work */
      keepTrying = 0;
    }
    catch (Fixable& f)
    {
      /* fix the problem */
      keepTrying = 1; // JFTHOI
    }
    catch (UnFixable& u)
    {
      /* prepare to terminate f */
      keepTrying = 0;
    }
  }
}




--
+---Robert C. Martin---+-RRR---CCC-M-----M-| R.C.M. Consulting         |
| rmartin@rational.com |-R--R-C----M-M-M-M-| C++/C/Unix Engineering    |
|     (Uncle Bob.)     |-RRR--C----M--M--M-| OOA/OOD/OOP Training      |
+----------------------+-R--R--CCC-M-----M-| Product Design & Devel.   |




Author: jimad@microsoft.com (Jim ADCOCK)
Date: 11 Nov 91 20:12:09 GMT
Raw View
In article <1991Nov8.141843.6034@cc.ic.ac.uk> rb@cc.ic.ac.uk (Robin Becker) writes:
|Since exceptions are semantically quite difficult and apparently not yet
|completely standardised I would oppose a mechanism which forbids
|resumption after some error correction.  I have in mind processing of
|high priority stuff when something minor occurs i.e. we're trying to
|shut down the nuclear reactor and the fuse on the outside lighting
|blows, it seems we should safely be able to ignore the latter.
|Any comments?  Robin

This issue was considered when the ANSI-C++ committee voted on including
templates in the language definition.  MartinO, I believe wrote up a
proposal on why resumption should be allowed as you require.  The
committee voted against resumption.

Seems to me at this point in time you are left with a number of
[reasonable] choices:

1) Get the ANSI-C++ working papers, and see if you don't agree with the
committee decision.

2) Review the ANSI-C++ working papers, and decide if they missed something
that you can write up and make such a convincing case that you can
get them to reverse their decision.

3) Lobby your vendor to allow resumption in their particular compiler.

4) Go program in some other language, if and when you can get a reasonable
compiler.

[I have no personal opinion on this particular matter :-]




Author: rmartin@erde.Rational.COM (Bob Martin)
Date: 14 Nov 91 17:22:31 GMT
Raw View
hansen@pegasus.att.com (Tony L. Hansen) writes:
>One proposal which has been bandied around a little bit is to extend the
>linkage specification extern "language" capability to specify an extern
>"company". One syntax would be something like:

> extern "MegaGlop::" {
>  whatever else would normally go in the header file
>  from MegaGlop
> }


I would like to see something along the lines of the following:

--------megaglop/category.hh------------
#category MegaGlop
#public:
  "megaglop/string.hh"
  "megaglop/complex.hh"
#private:
  "megaglop/string_support.hh"  /* nobody should be using this class
           /* except MegaGlop classes */
#end_category
-------------------------------

-------myFile.hh---------------
#include "megaglop/category.hh"  /* define the category */
#include "megaglop/string.hh" /* automatically causes all names declared
         /* within to be qualified with the category
                              /* name "MegaGlop" */

// string_support will certainly be included by "megaglop/string.hh" but since
// this file appears in the #private section, its name will not be introduced
// in the global scope....

Note that I did not #include "megaglop/complex.hh".   I don't always
want to  include all the specifications within a category.  The
#category statement simply tells the compiler/preprocessor which
include files belong to that category.

I can refer to MegaGlop's String class as MegaGlop::String.  I cannot
refer to MegaGlop's StringSupport class since its name is private to MegaGlop.

#category statements can nest, allowing categories within categories.
For example:

#category Vendors
#public:
   "megaglop/category.hh" /* the megaglop category */
   "cloneco/category.hh" /* more third party classes*/
#end_category

Now MegaGlop's string class can be refered to as
Vendors::MegaGlop::String.

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

I can't say that I have thought this through particularily well, but I
do hope that it sparks some conversation.
--
+---Robert C. Martin---+-RRR---CCC-M-----M-| R.C.M. Consulting         |
| rmartin@rational.com |-R--R-C----M-M-M-M-| C++/C/Unix Engineering    |
|     (Uncle Bob.)     |-RRR--C----M--M--M-| OOA/OOD/OOP Training      |
+----------------------+-R--R--CCC-M-----M-| Product Design & Devel.   |