Question

How do I create a list where each element can be of a different type?

What I am doing now is something along these lines:

typedef struct listitem
{
    int flavour;
    void *payload;
    struct listitem *next;
} listitem

And when accessing an item from this list, I check the value of flavour and then cast payload to the appropriate type. This approach seems a bit sledge-hammer to me.

What is the standard way to do this in C99?

Is there someway to infer the type of an object, given only its address?

Was it helpful?

Solution

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;
}

OTHER TIPS

Pointers you can just use a void *. Other types you can use a union:

typedef struct listitem
{
    int flavour; // type of data held
    union {
        int i;
        double d;
        float f;
        :
        :
    };
    struct listitem *next;
} listitem

Sorry, I misread your question. You have manage flavour yourself.

There's another way.

If you don't have many value for your flavour you can embed it the address. An address aligned to a power of two has its least significant bits to 0. In C11 you have a standard way of allocating aligned memory which can then be used to tag your pointers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top