bigTree
bigTree

Reputation: 2173

Understanding a C exception program

I am working on this example to try understand functions longjmp and setjmp:

#include <stdio.h>
#include <setjmp.h>

#define TRY do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){
#define CATCH } else {
#define ETRY } }while(0)
#define THROW longjmp(ex_buf__, 1)

int
main(int argc, char** argv)
{
   TRY
   {
      printf("In Try Statement\n");
      THROW;
      printf("I do not appear\n");
   }
   CATCH
   {
      printf("Got Exception!\n");
   }
   ETRY;

   return 0;
}

I don't understand the #defines at the beginning of the code:

1- What is the ex_buf__?

2- In the page from which I took this example, it is said:

When the THROW statement is executed it simply calls the longjmp function with the second parameter equals to 1 (or anything not 0).

Why is it possible to take any value not 0?

Upvotes: 1

Views: 186

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409166

The #define directive is a preprocessor directive. It's used to define macros used by the preprocessor to replace their invocation in other paces in the code.

For example, you have the following macro

#define TRY do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){

Whenever the preprocessor sees TRY elsewhere in the code, it's replaced by its contents. So the line

TRY

becomes

do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){

As for your other questions, the ex_buf__ is simply a variable declared (and defined) inside the loop created by the TRY macro expansion. It's scope is inside the loop, and all nested scopes inside the loop.

For the last question, see in the TRY macro the call to setjmp? It is part of a conditional statement in an if statement. Note the exclamation mark ! before the function call? That means the returned value from the function is negated, that is a zero value becomes one, and anything non-zero becomes zero. The longjmp function causes the code to unconditionally jump to the setjmp call, and makes setjmp return the value of the second argument to longjmp. Since the second argument to longjmp is non-zero, the expression !setjmp(...) will be zero, and the code jumps to the else part of the if statement, which is the CATCH part of the try-catch emulation.

Upvotes: 3

bestalign
bestalign

Reputation: 227

After preprocessing, your code becomes:

int
main(int argc, char** argv)
{
   do{
       jmp_buf ex_buf__;
       if( !setjmp(ex_buf__) )
       {
          printf("In Try Statement\n");
          longjmp(ex_buf__, 1);
          printf("I do not appear\n");
       }
       else
       {
           printf("Got Exception!\n");
       }
   }while(0);

   return 0;
}

jmp_buf and longjmp are declared in setjmp.h.

Upvotes: 2

Daniel A. White
Daniel A. White

Reputation: 190915

ex_buf__ is a jmp_buf that is declared in the TRY macro. longjmp will only jump on non-0 values kinda like an if statement.

Upvotes: 1

Related Questions