I just started reading this article about exception handling in c with the use of setjmp( jmp_buf ) and longjmp( jmp_buf, int ). So I basically build the linked list that uses the local variables from type xRecord and links it to the list. (Example 2) It works just fine. But in example 3 the steps get summarized into macros (XTRY and XEND). What irritates me most is that the actual switch statement of example 2 just "vanished" in 3.
Example 2:
#define DIVIDE_BY_ZERO -3
int SomeFunction(int a, int b)
{
if (b == 0) // can't divide by 0
XRaise(DIVIDE_BY_ZERO);
return a / b;
}
void main(void)
{
XRecord XData;
XLinkExceptionRecord(&XData);
switch (setjmp(XData.Context))
{
case 0: // this is the code block
{
int Result = SomeFunction(7, 0);
// continue working with Result
}
break;
case DIVIDE_BY_ZERO:
printf("a division by zero occurred\n");
break;
default:
printf("some other error occurred\n");
break;
case XFINALLY:
printf("cleaning up\n");
}
XUnLinkExceptionRecord(&XData);
}
Example 3:
void main(void)
{
XTRY
case XCODE: // this is the code block
{
int Result = SomeFunction(7, 0);
// continue working with Result
}
break;
case DIVIDE_BY_ZERO: // handler for a
specific exception
printf("a division by zero occurred\n");
break;
default: // default handler
printf("some other error occurred\n");
break;
case XFINALLY: // finally handler
printf("cleaning up\n");
XEND
}
My question is, how can I build these "opening and closing" macros?
If you compare the two examples, and keep in mind that C macros are simple text substitutions, what the macros should be is evident:
#define XTRY XRecord XData; \
XLinkExceptionRecord(&XData); \
switch (setjmp(XData.Context)) \
{
#define XEND } \
XUnLinkExceptionRecord(&XData);
Note the use of \
to allow the macro to span more than one line.
You may also want to have the macros open and close a new scope (by adding {
and }
), so that using the macros multiple in succession doesn't give an error due to multiple definitions of the variable XData
. You can also use the do / while(0)
trick to allow these macros to be placed directly inside if
, for
, etc. without issues.