Xref: utzoo comp.lang.c++:4393 gnu.g++:345
Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.csd.uwm.edu!gem.mps.ohio-state.edu!ginosko!usc!polyslo!ttwang
From: ttwang@polyslo.CalPoly.EDU (Thomas Wang)
Newsgroups: comp.lang.c++,gnu.g++
Subject: Re: Unwinding vs destructors
Message-ID: <13635@polyslo.CalPoly.EDU>
Date: 16 Aug 89 21:09:16 GMT
References: <13145@well.UUCP>
Reply-To: ttwang@polyslo.CalPoly.EDU (Thomas Wang)
Distribution: usa
Organization: Cal Poly State University -- San Luis Obispo
Lines: 69

nagle@well.UUCP (John Nagle) writes:

>    C++ destructors provide a means to force cleanup of an object as it
>disappears upon exit from a scope.  Unfortunately, the "longjmp" mechanism
>evades destructor processing.  "longjmp" is an old hack, only sort of part
>of C.  But it is useful.  Should C++ have a better escape mechanism,
>along the lines of "throw" and "return-from" in Common LISP or "raise" in
>Ada?  With those mechanisms, appropriate cleanup processing is performed
>as the scopes unwind.  But C++ lacks such a mechanism.

I would suggest something like the following:

extern int error_code, error_type;

real square_root(real val)
{
  real result;
  pre_condition : val > 0.0;
  post_condition: (result * result + .1 > val) && (result * result - .1 < val);

  char* tempbuf = (char*) malloc(80 * sizeof(char));
  if (tempbuf == 0)
  {
    error_code = 1;
    fail; // goto the recovery handler.  If no recovery handler exists,
          // pop stack & propogate failure upwards.
  }
  calculation_follows();
  return result;
recovery:
  switch (error_type)
  {
  case 0: // pre-condition failed
    if (val > 0.0)
    {
       val = - val;
       retry; // retry will pop all local variables, and goto top of function
    }
    break; // if we falls through, failure will propogate upward toward
           // main() function
  case 1: // post-condition failed
    cout << "incorrect result was generated.\n";
    break;
  case 2: // class-invarient failed
    break;
  case 3: // raised by the 'fail' statement
    if (error_code == 1)
      cout << "out of memory\n";
    break;
  case 4: // previous failure propogated to here
    break;
  }
}

>     One could argue that such mechanisms violate the "no hidden machinery"
>concept of C.  But C++ already has destructors, functions which are invoked
>by the language system, not explicitly by the user.  What do people think?

I think this error handling mechanism is fairly explicit, and replaces all
instances of ad-hoc error checkings.  The mechanism is borrowed from
Eiffel if you have not noticed already.

>					John Nagle

 -Thomas Wang ("This is a fantastic comedy that Ataru and his wife Lum, an
                invader from space, cause excitement involving their neighbors."
                  - from a badly translated Urusei Yatsura poster)

                                                     ttwang@polyslo.calpoly.edu