Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!dali.cs.montana.edu!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!wuarchive!ukma!hsdndev!cmcl2!adm!news From: Slomcenski.WBST129@xerox.com Newsgroups: comp.lang.pascal Subject: Re: Turbo Pascal for Windows - Catch & Throw Message-ID: <26994@adm.brl.mil> Date: 23 May 91 18:15:00 GMT Sender: news@adm.brl.mil Lines: 86 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