Local Goto with setjmp() and longjmp()

There is no reason why you cannot use setjmp() and longjmp() to perform local goto activities. Let us start with a very simple program. Click here to download a copy.

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

void  main(int argc, char *argv[])
{
     jmp_buf   Buffer;
     long      fact, i, number;

     number = atoi(argv[1]);
     fact   = i = 1;  
     setjmp(Buffer); 
     fact *= i;      
     printf("%d! = %d\n", i, fact);
     i++;
     if (i <= number)         
          longjmp(Buffer, 1); 
}
In this program, jump buffer Buffer is setup as the destination "label" for the longjmp() call. The returned value of setjmp() is ignored.

With the power of setjmp() and longjmp(), we can certainly do more interesting (or weird, depending on your point of view) programming practice. The following is another, but longer, program. Click here to download a copy.

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

void  main(int argc,  char *argv[])
{
     jmp_buf   Return;           
     jmp_buf   Counting;          
     int       MaxCount;          
     int       even, odd, count;
     int       number;

     MaxCount = atoi(argv[1]);

     printf("Even-Odd Random Number Counting:\n");
     switch (setjmp(Return)) {       
          case 0:  goto LOOP;        
          case 1:  longjmp(Counting, 1);   
          case 2:  printf("There are %d even and %d odd random numbers\n",
                           even, odd); 
     }
     exit(0);

LOOP:                              
     even = odd = count = 0;
     srand((unsigned int) time(NULL));

     if (setjmp(Counting) == 0)    
          longjmp(Return, 1);    
     else {                      
          number = rand();       
          printf("  Random number = %d ", number);
          if ((number % 2) == 0) {
               printf("(even)\n");
               even++;
          }
          else {
               printf("(odd)\n");
               odd++;
          }
          if (even + odd != MaxCount)
               longjmp(Return, 1);  
          else
               longjmp(Return, 2); 
     }
}

This program requires some explanation.