Skip to content

Instantly share code, notes, and snippets.

@delcypher
Last active April 29, 2016 13:43
Show Gist options
  • Save delcypher/e5d2155466c851ed20ac0257115f920e to your computer and use it in GitHub Desktop.
Save delcypher/e5d2155466c851ed20ac0257115f920e to your computer and use it in GitHub Desktop.
Demonstration of poor man's try-catch construct in C99 using preprocessor macros
/* Demonstration of a poor man's try-catch construct in C99 using
* C preprocessor macros to make the syntax look vaguely like
* try-catch constructs in other lagnuages. This implementation
* is incredibly bad because C macros are very error prone and
* this implementation cannot have nested try-catch constructs
*/
#include <stdio.h>
#include <assert.h>
#define TRY ; _Pragma("pop_macro(\"EXCEPTION_EXIT_LABEL\")")
#define CATCH(L) goto EXCEPTION_EXIT_LABEL; L :
#define END_TRY_CATCH EXCEPTION_EXIT_LABEL : ;
#define RAISE(X) goto X
// Exception exit block labels (this allows at most two try catch block declarations)
// inside a function
#define EXCEPTION_EXIT_LABEL _Pragma("GCC error \"Run out of exit labels\"")
#pragma push_macro("EXCEPTION_EXIT_LABEL")
#define EXCEPTION_EXIT_LABEL exception_exit_1
#pragma push_macro("EXCEPTION_EXIT_LABEL")
#define EXCEPTION_EXIT_LABEL exception_exit_0
#pragma push_macro("EXCEPTION_EXIT_LABEL") // First push here is meant to be popped by first TRY
int main(int argc, char** argv) {
TRY {
printf("start\n");
if (argc == 2)
RAISE(bar);
if (argc > 1)
RAISE(foo);
}
CATCH(foo) {
printf("catch foo\n");
}
CATCH(bar) {
printf("catch bar\n");
}
END_TRY_CATCH
printf("done0\n");
printf("Let's try more things\n");
TRY {
printf("second\n");
if (argc > 2)
RAISE(baz);
}
CATCH(baz) {
printf("catch baz\n");
}
END_TRY_CATCH
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment