No, C doesn't provide you with reflection facilities, i.e. the capability to infer the type of an object based on its address. You're going to have to manage that yourself. You're doing the right thing, but you're going to have to manage the flavour yourself. Others have pointed out how to lessen the pain by putting all the alternative types in a union, so that you don't have to cast all the time. You may be well off writing a few inline functions that hide all the unions and what not. To get an idea:
typedef struct listitem
{
int flavour;
union {
int i;
char * str;
};
struct listitem * next;
};
int int_item(struct listitem * item)
{
if (flavour != FLAVOUR_INT)
error("Not an integer");
return item->i;
}
char * string_item(struct listitem * item)
{
if (flavour != FLAVOUR_STRING)
error("Not a string");
return item->str;
}