1

Possible Duplicate:
ANSI C equivalent of try/catch?

Is there a way to skip critical code ? More or less like try-catch in modern programming languages. Just now I'm using this technique to spot errors:

bindSignals();
{
    signal(SIGFPE, sigint_handler);
    // ...
}

int main(void)
{
    bindsignals();
    int a = 1 / 0; // division by zero, I want to skip it
    return 0;
}

The problem is if I don't exit the program in the handler I get the very same error again and again. If possible I would like to avoid goto. I also heard about "longjump" or something. Is it worth to (learn to) use ?

Community
  • 1
  • 1
Bitterblue
  • 13,162
  • 17
  • 86
  • 124
  • This link may be useful: [**Notes on Handlers for User-Defined Signals**](http://support.sas.com/documentation/onlinedoc/sasc/doc/lr2/lrv2ch12.htm) and also [**Is there any way to create a user defined signal in Linux?**](http://stackoverflow.com/questions/5741604/is-there-any-way-to-create-a-user-defined-signal-in-linux) – Grijesh Chauhan Jan 16 '13 at 13:25
  • 1
    C is a modern programming language :) – Jens Gustedt Jan 16 '13 at 13:28
  • 1
    Also why would you avoid `goto`? Don't get yourself caught in some ideology wars, there are situations where `goto` is completely adequate, namely error handling as in your case. – Jens Gustedt Jan 16 '13 at 13:29

3 Answers3

3

Well, you can probably accomplish something like that using longjmp(), yes.

Possibly with the "help" of some macros. Note the comment on the manual page, though:

longjmp() and siglongjmp() make programs hard to understand and maintain. If possible an alternative should be used.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 2
    Also, missing `volatiles` around `setjmp()` and `*longjmp()` will induce pretty nasty bugs. – Alexey Frunze Jan 16 '13 at 13:24
  • @unwind Can you explain what's the difference between longjmp and siglongjmp ? Save and restore signals ? What are the default signal states ? – Bitterblue Jan 16 '13 at 13:55
0

I'll throw my two cents in on this. C does not have a mechanism like the try/catch that other languages support. You can build something using setjmp() and longjmp() that will be similar, but nothing exactly the same.

Here's a link showing a nice way of using setjmp and longjmp to do what you were thinking; and a code snippet from the same source:

   jmp_buf jumper;

   int SomeFunction(int a, int b)
   {
      if (b == 0) // can't divide by 0
         longjmp(jumper, -3);
      return a / b;
   }

   void main(void)
   {
      if (setjmp(jumper) == 0)
      {
         int Result = SomeFunction(7, 0);
         // continue working with Result
      }
      else
         printf("an error occured\n");
   }

I'm currently going from C to Java and I'm having a hard time understanding why you'd use try/catch in the first place. With good error checking you should be fine, always always always use the values that are returned from functions, check the errono values, and validate any user input.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • You'll love try and catch when you understand and start to use them. Some errors you cannot avoid and sometimes you have to raise exceptions yourself. Also it allows you to develop waaaay more faster than in C. Imagine the file you checked the existence of is deleted in the moment between checking and opening (i'm not a pro in C). ^^ – Bitterblue Jan 16 '13 at 14:10
  • @mini-me - in that case I'd check the result of the `open()` command, see it failed and get the `strerror(errno)` value to see it's not present anymore. ;) I do see your point and how it could be faster... just hard to get around it not being there, which is sort of like you coming to the C world, try/catch isn't here, so you learn to live that way. ^^ – Mike Jan 16 '13 at 14:16
0

I'm done. That's how my code looks like now. Almost like Java and C#.

#include <setjmp.h>

jmp_buf jumper;

#define try           if (setjmp(jumper) == 0)
#define catch         else
#define skip_to_catch longjmp(jumper, 0)

static void sigint_handler(int sig)
{
    skip_to_catch;
}

int main(void)
{
    // init error handling once at the beginning
    signal(SIGFPE,  sigint_handler);

    try
    {
        int a = 1 / 0;
    }
    catch
    {
        printf("hello error\n");
    }
    return 0;
}
Bitterblue
  • 13,162
  • 17
  • 86
  • 124