Skip to content

Instantly share code, notes, and snippets.

@lambdageek
Last active November 15, 2016 21:31
Show Gist options
  • Save lambdageek/657999ed236da904ee5d5c116a5f11f2 to your computer and use it in GitHub Desktop.
Save lambdageek/657999ed236da904ee5d5c116a5f11f2 to your computer and use it in GitHub Desktop.
BEFORE_AFTER_BLOCK macro
#include <stdio.h>
#define EMPTY /* empty */
#define CONCAT_HELPER(x,y) x ## y
#define CONCAT(x,y) CONCAT_HELPER(x,y)
#define LABEL_MAKER(id) CONCAT(id,__LINE__)
#define BEFORE_AFTER_BLOCK(decl, before_block, after_block) \
if (0) \
LABEL_MAKER(finished): EMPTY; \
else if (0) \
LABEL_MAKER(handle_break): \
break; /* if you get a compiler error here, you used BLOCK outside of any loop */ \
else \
for (decl; ;) \
if (1) { \
before_block; \
goto LABEL_MAKER(body); \
} else \
while (1) \
if (1) { \
after_block; \
goto LABEL_MAKER(handle_break); \
} else \
while (1) \
if (1) { \
after_block; \
goto LABEL_MAKER(finished); \
} else \
LABEL_MAKER(body):
#define LOG_LOOP(var_to_print) \
BEFORE_AFTER_BLOCK(FILE *log = stderr, \
{ fprintf (log, "entering block (" # var_to_print " = %d)\n", var_to_print);}, \
{ fprintf (log, "exiting block, (" # var_to_print " = %d)\n", var_to_print); })
int
collatz (int n) {
int g = 0;
while (1) LOG_LOOP(n)
{
if (n < 0) {
n = -n;
continue;
}
if (n == 1)
break;
if (n % 2)
n = 3 * n + 1;
else
n = n / 2;
g++;
}
/* while (1) LOG_LOOP(g)
{
g++;
if (g > 100)
break;
}
*/
return g;
}
int
main (int argc, char ** argv)
{
printf ("took %d steps\n", collatz (-10));
}
@lambdageek
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment