Reputation: 6424
In plain c, 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?
Upvotes: 2
Views: 89
Reputation: 73366
No, use void*
and then cast.
One could think that I can use a void*
and then check about the casting inside the function, and if not the expected type, raise an error, but no, you cannot do that either, since void*
loses all its type information.
Damn I am writing just before going into the shower. I couldn't resist! BRB :) -- OK, turns out R..'s answer from the future is the correct one! ;)
Upvotes: 0
Reputation: 96
As Houman pointed out, you can use a union to do the job, however, you still have the problem that you must identify the type that is set in the union type. You can solve that using an enum to identify the type inside your function.
union myUnion {
int* intPointer,
MyStruct* myStructPointer
};
enum typeEnum {
INT,
MYSTRUCT
};
void myfunction(union myUnion union, enum typeEnum type) {
if (type == INT)
// you got an integer
else if (type == MYSTRUCT)
// you got a struct
// You can add future additions here
}
Upvotes: 1
Reputation: 215257
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)) )
Upvotes: 2
Reputation: 141586
You could do this:
void myfunction(void *s)
{
if ( *(int *)s == MAGIC )
{
MyStruct *p = s;
printf("%s\n", p->content);
}
}
However this design makes it easy to write buggy code that the compiler will not catch for you, so I would recommend coming up with a slightly different design (e.g. tagged unions).
Upvotes: 0