#include #define Result_t(T, E) \ struct Result_##T##_##E { \ bool is_ok; \ union { \ T value; \ E error; \ }; \ } #define Ok(T, E) \ (struct Result_##T##_##E) { \ .is_ok = true, .value = (T)_OK_IMPL #define _OK_IMPL(...) \ __VA_ARGS__ \ } #define Err(T, E) \ (struct Result_##T##_##E) { \ .is_ok = false, .error = (E)_ERR_IMPL #define _ERR_IMPL(...) \ __VA_ARGS__ \ } typedef const char *ErrorMessage_t; Result_t(int, ErrorMessage_t) my_func(int i) { if (i == 42) return Ok(int, ErrorMessage_t)(100); else return Err(int, ErrorMessage_t)("Cannot do the thing"); } int main(void) { Result_t(int, ErrorMessage_t) x = my_func(42); if (x.is_ok) { printf("%d\n", x.value); } else { printf("%s\n", x.error); } }