#include #include #include #include #include #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"); }