Last active
April 29, 2016 13:43
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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