ANSI C equivalent of try/catch?
Generally, you don't.
It's possible to use setjmp
and longjmp
to build something fairly similar to try/catch, although there's no such thing in C as destructors or stack unwinding, so RAII is out of the question. You could even approximate RAII with a so-called "cleanup stack" (see for example Symbian/C++), although it's not a very close approximation, and it's a lot of work.
The usual way to indicate errors or failure in C is to return a value indicating success status. Callers examine the return value and act accordingly. See for example the standard C functions: printf
, read
, open
, for ideas how to specify your functions.
When mixing C and C++ code, you must ensure that a C++ exception never reaches C code. When writing C++ functions that will be called from C, catch everything.
There is the classic unwinding goto
s pattern:
FILE *if = fopen(...);FILE *of = NULL;if (if == NULL) return; of = fopen(...);if (of == NULL) goto close_if;/* ...code... */if (something_is_wrong) goto close_of;/* ... other code... */close_of: fclose(of);close_if: fclose(if);return state;
Alternately you can fake it in a limited way by isolating the "try" code in another function
int try_code(type *var_we_must_write, othertype var_we_only_read /*, ... */){ /* ...code... */ if (!some_condition) return 1; /* ...code... */ if (!another_condition) return 2; /* ...code... */ if (last_way_to_fail) return 4; return 0;}void calling_routine(){ /* ... */ if (try_code(&x,y/*, other state */) ) { /* do your finally here */ } /* ... */}
but neither approach is fully equivalent. You have to manage all the resources yourself, you don't get automatic rollback until a handler is found, and so on...