nagle@well.UUCP (John Nagle) (08/15/89)
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. 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? John Nagle
ttwang@polyslo.CalPoly.EDU (Thomas Wang) (08/17/89)
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
ted@nmsu.edu (Ted Dunning) (08/23/89)
In article <13635@polyslo.CalPoly.EDU> ttwang@polyslo.CalPoly.EDU (Thomas Wang) writes: 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; ... sample code ... 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. i didn't actually notice. i have implemented a unwind_protect/catch/throw mechanism for unadorned c that would be easy to move to c++. this mechanism is based on the semantics of these constructs in common lisp and should provide a robust non-local return mechanism if longjmp is not used. it is probably desirable that an error/debug mechanism be implemented alongside the catch/throw mechanism based on the experience in common lisp. if anyone is interested, i can either post/email the code (it is really pretty small). -- ted@nmsu.edu Most of all, he loved the fall when the cottonwoods leaves turned gold and floated down the trout streams under the clear blue windswept skies.