Skip to content

Instantly share code, notes, and snippets.

@eevee
Created September 18, 2012 21:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eevee/3746130 to your computer and use it in GitHub Desktop.
Save eevee/3746130 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
static jmp_buf _strlen_jump;
static void* _strlen_label;
static void* _strlen_done_label;
static void _strlen_divzero(int signal) {
_strlen_label = _strlen_done_label;
longjmp(_strlen_jump, 1);
}
int unconditional_strlen(char* s) {
int ret = 0;
volatile int junk; // prevent optimizing the division away
_strlen_label = &&_strlen_redo;
_strlen_done_label = &&_strlen_done;
signal(SIGFPE, _strlen_divzero);
setjmp(_strlen_jump);
goto *_strlen_label;
_strlen_redo:
junk = s[0] / s[0];
ret++;
s++;
goto *_strlen_label;
_strlen_done:
signal(SIGFPE, SIG_IGN);
return ret;
}
int main(int argc, char** argv) {
assert(argc > 1);
printf("%d\n", unconditional_strlen(argv[1]));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment