From: Paul Brannan Date: 2001-10-17T23:26:58+09:00 Subject: [ruby-talk:22673] Re: Exception handling in c On Wed, 17 Oct 2001 vrabel@burncd.sk wrote: > Hi, > > is there another way, how to handle exception in c, apart of the rb_rescue? > > Thanx > > Peter Vrabel Generally speaking, you don't need to actually catch the exception; in fact, rb_ensure() will do just fine. It's not 100% convenient, because you still have to break your function into multiple little functions. Very often, I find that it is possible to lay out my code in such a way that I don't ever need to explicitly handle Ruby exceptions. For example: VALUE foo(VALUE self, VALUE param1, VALUE param2) { Foo *foo; int x; char *y; Bar *b1, *b2; FILE *fp; /* I think this can throw, but it won't hurt anything */ Data_Get_Struct(self, Foo, foo); /* This can throw too, but it also won't hurt anything */ x = NUM2INT(param1); /* If I were to use malloc() here, then I would need to use rb_ensure * to make sure that the memory gets freed. */ b1 = ALLOC(Bar); /* Here's another option, but is faster since the memory is allocated * on the stack. */ b2 = ALLOCA_N(Bar, 1); /* Now I'm opening a file, but I don't want to use the Ruby file I/O. * I must be sure to close the file when I am done. */ fp = fopen("foo", "w+"); /* Assume this is successful */ Data_Wrap_Struct(rb_cObject, NULL, fclose, fp); /* Do some processing here ... */ /* This can throw, but it's OK */ y = STR2CSTR(param2); return INT2NUM(atoi(y)); } In C++, exception safety is much more complex, especially if you want to be able to declare automatic objects on the stack. The trickiest problem in C, though, is not leaking memory/resources, but leaving all your objects in a consistent state. In this example, if I were to raise an exception in the middle of my processing, then even though the file would get closed, I would probably be leaving the file half-written. In that case, I cannot be certain that the data in the file is correct. Paul