[comp.lang.pascal] Turbo Pascal for Windows - Catch & Throw

Slomcenski.WBST129@xerox.com (05/24/91)

A question was asked on the use of "Catch" and "Throw" in Turbo Pascal for
Windows (Windows API routines).  I no longer have the original message to
respond to, but here is an explanation of Catch and Throw that may be useful
for anyone using Turbo for Windows:
 
The Catch function and the Throw procedure together implement a sort of
universal "GOTO" utility that has the ability to cross block scope boundaries.

When a call to Catch is encountered in the code, the current state of the
program is captured into an 8 word array (TCatchBuf). This program
information is sufficient to later re-establish the state of the stack and
registers to the condition in effect at the place Catch was called; allowing
a return to this point in the code from anywhere else in the code. By
convention, the original call to Catch returns a zero (0) indicating that the
current state information is captured.

A subsequent call to the procedure Throw (passing in a CatchBuf that was
captured by some earlier Catch) will in effect perform a "GOTO" (or jump)
to the corresponding Catch that originally captured the state information,
with one very important difference -- the ThrowBack value passed into
Throw is "returned" from the Catch function instead of zero (0). In this way,
Throw acts as an indexed "GOTO" (or jump) to some corresponding Catch.

One very critical caution should be observed when using Catch and Throw.
NEVER jump to a Catch that is at a more deeply nested scope level than the
Throw from which it came. This will corrupt the stack and will probably
crash or hang the system. It is OK to jump to a Catch at the same level or
any higher level, as the stack will be preserved in these cases.

Typically, Catch and Throw are used to implement an error handling strategy
that efficiently implements testing of error conditions, and "backs-out" to
some higher level if an error occurs. Here is an outline example:

  PROCEDURE DoSomething;
    VAR
      stateInfo: TCatchBuf;

    PROCEDURE NestedStep1;
      BEGIN
        { ..... }
        IF error THEN Throw(stateInfo, 1); { GOTO error handler }
        { ..... }
      END;

    PROCEDURE NestedStep2;
      BEGIN
        { ..... }
        IF error THEN Throw(stateInfo, 2); { GOTO error handler }
        { ..... }
      END;

    PROCEDURE NestedStep3;
      BEGIN
        { ..... }
        IF error THEN Throw(stateInfo, 3); { GOTO error handler }
        { ..... }
      END;

    BEGIN { DoSomething }

      CASE Catch(stateInfo) OF
        0: { initial return from Catch -- do normal processing } 
          BEGIN
            NestedStep1;
            NestedStep2; { only if step 1 worked }
            NestedStep3; { only if steps 1 & 2 worked }
          END;
        1: { Throw returned a value of 1 }
          BEGIN
            { process error #1 }
          END;
        2: { Throw returned a value of 2 }
          BEGIN
            { process error #2 }
          END;
        ELSE { Throw returned some other value }
          BEGIN
            { process other error condition }
          END;
    END; {case}

    END; { DoSomething }

Hope this helps ---
  Bob Slomcenski

smith@ctron.com (Larry Smith) (05/24/91)

In article <26994@adm.brl.mil> Slomcenski.WBST129@xerox.com writes:
>
>A question was asked on the use of "Catch" and "Throw" in Turbo Pascal for
>When a call to Catch is encountered in the code, the current state of the
>program is captured into an 8 word array (TCatchBuf). This program
>information is sufficient to later re-establish the state of the stack and

But can these facilities be used to implement threads?  Most setjmp/longjmp
routines in C libraries these days can also save stack information, so you
can allocate new stacks to be used for different chunks of code.  This lets
you implement Modula-style processes (c-style threads) pretty easily.  Turbo
C *does* store the required information, and I have seen a friends home-built
thread package running on it.  Can Turbo Pascal do the same?

>One very critical caution should be observed when using Catch and Throw.
>NEVER jump to a Catch that is at a more deeply nested scope level than the
>Throw from which it came. This will corrupt the stack and will probably

With this caveat, it doesn't sound like it, and that's really sad.  Lack
of threads is the one thing I truly need and the one thing Turbo Pascal
seems to lack.  Sigh.  I really prefer Pascal, but it looks like C++ is
going to be the choice.

-- 

Larry Smith
smith@ctron.com
The usual disclaimer stuff...