Skip to content

Instantly share code, notes, and snippets.

@theMackabu
Created March 15, 2026 21:14
Show Gist options
  • Select an option

  • Save theMackabu/87462690ec724c8f38fe932daa89ce76 to your computer and use it in GitHub Desktop.

Select an option

Save theMackabu/87462690ec724c8f38fe932daa89ce76 to your computer and use it in GitHub Desktop.
undefined behavior land
#include <stdio.h>
#define fmt(x) _Generic((x), \
int: "%d", \
long: "%ld", \
float: "%f", \
double: "%lf", \
char: "%c", \
char*: "%s", \
const char*: "%s", \
default: "%p" \
)
#define print_one(x) printf(fmt(x), x)
#define PRINT_1(a) print_one(a)
#define PRINT_2(a,b) print_one(a); print_one(b)
#define PRINT_3(a,b,c) print_one(a); print_one(b); print_one(c)
#define PRINT_4(a,b,c,d) print_one(a); print_one(b); print_one(c); print_one(d)
#define PRINT_5(a,b,c,d,e) print_one(a); print_one(b); print_one(c); print_one(d); print_one(e)
#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
#define print(...) GET_MACRO(__VA_ARGS__, PRINT_5,PRINT_4,PRINT_3,PRINT_2,PRINT_1)(__VA_ARGS__)
int main(void){
print("This print works in c and does not care about types\n");
char* name = "Pablo";
int age = 67;
print("this guy's name is ", name, " and he's ", age, " years old\n");
}
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <signal.h>
#include <setjmp.h>
#define SENTINEL 0xDEADBEEFCAFEBABEULL
static sigjmp_buf probe_jmp;
static void probe_handler(int sig) { siglongjmp(probe_jmp, 1); }
static int can_read(uint64_t v) {
struct sigaction sa = {
.sa_handler = probe_handler
}, old_bus, old_segv;
sigaction(SIGBUS, &sa, &old_bus);
sigaction(SIGSEGV, &sa, &old_segv);
volatile int ok = 0;
if (sigsetjmp(probe_jmp, 1) == 0) {
(void)*(volatile char *)(uintptr_t)v;
ok = 1;
}
sigaction(SIGBUS, &old_bus, NULL);
sigaction(SIGSEGV, &old_segv, NULL);
return ok;
}
__attribute__((noinline))
static void __print_inner(int dummy, ...) {
enum { T_INT, T_STR, T_DBL, T_COUNT };
va_list ap;
va_start(ap, dummy);
uint64_t *slot = (uint64_t *)(void *)ap;
static const void *dispatch[] = {
[T_INT] = &&l_int,
[T_STR] = &&l_str,
[T_DBL] = &&l_double,
};
while (*slot != SENTINEL) {
uint64_t v = *slot++;
uint8_t t = T_INT;
if (v >= 0x1000 && v <= 0x0000ffffffffffff && can_read(v)) {
unsigned char c = *(unsigned char *)(uintptr_t)v;
if ((c >= 0x20 && c < 0x7f) || c == '\n' || c == '\t' || c == '\r' || c == '\0') t = T_STR;
}
if (t == T_INT && v > 0x7FFFFFFF) {
uint64_t exp = (v >> 52) & 0x7FF;
if (exp > 0 && exp < 0x7FF) t = T_DBL;
}
if (t < T_COUNT && dispatch[t]) goto *dispatch[t];
continue;
l_double: {
double d;
__builtin_memcpy(&d, &v, 8);
printf("%g", d);
continue;
}
l_int: printf("%d", (int)v); continue;
l_str: printf("%s", (const char *)(uintptr_t)v); continue;
}
va_end(ap);
}
#define print(...) __print_inner(0, __VA_ARGS__, SENTINEL)
int main(void) {
print("This print works in c and does not care about types\n");
char *name = "Pablo";
int age = 67;
double pi = 3.14159;
long big = 42L;
print("name: ", name, " age: ", age, " pi: ", pi, " big: ", big, "\n");
}
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <signal.h>
#include <setjmp.h>
#define SENTINEL 0xDEADBEEFCAFEBABEULL
static sigjmp_buf probe_jmp;
static void probe_handler(int sig) { siglongjmp(probe_jmp, 1); }
__attribute__((noinline))
static void __print_inner(int dummy, ...) {
enum { T_INT, T_STR, T_DBL, T_COUNT };
va_list ap;
va_start(ap, dummy);
uint64_t *slot = (uint64_t *)(void *)ap;
static const void *dispatch[] = {
[T_INT] = &&l_int,
[T_STR] = &&l_str,
[T_DBL] = &&l_double,
};
struct sigaction sa = {.sa_handler = probe_handler}, ob, os;
sigaction(SIGBUS, &sa, &ob);
sigaction(SIGSEGV, &sa, &os);
while (*slot != SENTINEL) {
uint64_t v = *slot++;
uint8_t t = T_INT;
if (sigsetjmp(probe_jmp, 1) == 0) {
uint32_t is_str;
__asm__ volatile(
"ldrb %w[c], [%[ptr]]\n\t"
"sub %w[r], %w[c], #0x20\n\t"
"cmp %w[r], #0x5F\n\t"
"cset %w[r], lo\n\t"
"sub %w[c], %w[c], #9\n\t"
"cmp %w[c], #5\n\t"
"csinc %w[r], %w[r], %w[r], hs"
: [r] "=&r"(is_str), [c] "=&r"((uint32_t){0})
: [ptr] "r"((void*)(uintptr_t)v)
: "cc", "memory"
);
if (is_str) t = T_STR;
}
if (t == T_INT && v > 0x7FFFFFFF) {
uint32_t is_dbl;
__asm__ volatile(
"ubfx %w[e], %w[hi], #20, #11\n\t"
"sub %w[e], %w[e], #1\n\t"
"cmp %w[e], #0x7FE\n\t"
"cset %w[e], lo"
: [e] "=r"(is_dbl) : [hi] "r"((uint32_t)(v >> 32)) : "cc"
);
if (is_dbl) t = T_DBL;
}
if (t < T_COUNT) goto *dispatch[t];
continue;
l_str: printf("%s", (const char *)(uintptr_t)v); continue;
l_double: { double d; __builtin_memcpy(&d, &v, 8); printf("%g", d); continue; }
l_int: printf("%d", (int)v); continue;
}
sigaction(SIGBUS, &ob, NULL);
sigaction(SIGSEGV, &os, NULL);
va_end(ap);
}
#define print(...) __print_inner(0, __VA_ARGS__, SENTINEL)
int main(void) {
print("This print works in c and does not care about types\n");
char *name = "Pablo";
int age = 67;
double pi = 3.14159;
long big = 42L;
print("name: ", name, " age: ", age, " pi: ", pi, " big: ", big, "\n");
}
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <signal.h>
#include <setjmp.h>
#define SENTINEL 0xDEADBEEFCAFEBABEULL
static sigjmp_buf jmp;
static void handler(int s) { siglongjmp(jmp, 1); }
static void _print(int d, ...) {
va_list ap; va_start(ap, d);
uint64_t *slot = (uint64_t *)(void *)ap;
struct sigaction sa = {.sa_handler = handler}, ob, os;
sigaction(SIGBUS, &sa, &ob); sigaction(SIGSEGV, &sa, &os);
for (uint64_t v; (v = *slot++) != SENTINEL;) {
int t = 0;
if (!sigsetjmp(jmp, 1)) {
unsigned char c = *(char *)(uintptr_t)v;
t = (c - 9u < 5) || (c - 0x20u < 0x5F);
}
if (!t && ((v >> 52 & 0x7FF) - 1u < 0x7FE)) t = 2;
double f; __builtin_memcpy(&f, &v, 8);
t == 1
? printf("%s", (char *)(uintptr_t)v)
: t == 2 ? printf("%g", f)
: printf("%d", (int)v);
}
sigaction(SIGBUS, &ob, 0); sigaction(SIGSEGV, &os, 0);
}
#define print(...) _print(0, __VA_ARGS__, SENTINEL)
int main(void) {
print("This print works in c and does not care about types\n");
char *name = "Pablo";
int age = 67;
double pi = 3.14159;
long big = 42L;
print("name: ", name, " age: ", age, " pi: ", pi, " big: ", big, "\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment