Search code examples
cfunctionpointersoverloadinggeneric-programming

Can you allow one of a few types of pointers as an argument without void*?


In plain , I have a situation where I would like to allow a function to accept multiple types of pointers. To illustrate my situation, here could be one use case:

void myfunction([int* or char*] value) {
    *value = 0xdd;  // safe since value is at least as big as a char*
}

And here is another:

#define MAGIC 0xabcdef0
typedef struct {
    int magic;
    char* content;
} MyStruct;

void myfunction([int* or MyStruct*] value) {
    if (*value != MAGIC) {
        printf("Got an int\n");
    } else {
        printf("Got a MyStruct\n");
    }
}

// example:
int input1 = 0;
MyStruct input2 = { MAGIC, "hello world" };
myfunction(input1);  // "Got an int"
myfunction(input2);  // "Got a MyStruct"

Both of these situations could be made possible with a void* parameter type, but that would in effect allow any type of pointer to be passed in without a compile error. Is there a way to restrict the function to accept only a specific subset of pointer types?


Solution

  • If you can use features that are new in C11, the _Generic keyword can solve your problem:

    void myfunction(void *value) {
        // ...
    }
    #define myfunction(x) myfunction( \
        _Generic((x), char *: (x), int *: (x)) )