#include <stdio.h>
#include <stdlib.h>

typedef enum {
	INT,
	STR,
} type;

typedef struct {
	type type;
	union {
		char *s;
		int i;
	};
} variant_t;

#define VARIANT(x) _Generic((x), \
	int: ((variant_t){.type = INT, .i = x}), \
	char*: ((variant_t){.type = STR, .s = x}) \
)

void foo_int(int i)
{
	printf("Integer %d\n", i);
}

void foo_str(char *s)
{
	printf("String \"%s\"\n", s);
}

#define foo(x) (_Generic((x), \
	int: foo_int, \
	char*: foo_str \
)(x))

void dynamic_foo(variant_t pitux)
{
	switch (pitux.type) {
		case INT: foo(pitux.i); break;
		case STR: foo(pitux.s); break;
		default: error("Error!"); break;
	}
}

int main(void)
{
	for (int i = 0; i < 10; ++i) {
		dynamic_foo(rand() & 1 ? VARIANT(42): VARIANT("forty two"));
	}
	return 0;
}