How can I write a function which accepts a parameter of a generic type in C? (such as an int, a char...)
What you are looking for is called a variadic function. Linked below is a Wikipedia article on the topic:
I'd personally do it like this:
1) send a pointer to void * as the first parameter
2) send a second parameter which tells you what the void * is (an enum for the possibilities) and cast parameter 1 to that
This would make you write ugly code with lots of switches, but might work if done carefully and thoroughly tested.
Something like:
// the enum:
BYTE_VALUE = 1; INT_VALUE = 2, CHAR_VALUE = 3 etc
// the function
int parse(void *arg, enum_type arg_type)
{
if (arg == NULL) return -1;
switch(arg_type)
{
case BYTE_VALUE:
byte value = (byte) *arg;
// do work here
case INT_VALUE:
// etc
}
return something;
}
Edit: that is assuming you don't want variadic functions (which did not seem to me were what you wanted)
Using a void*
is the usual way. Check for example the implementation of memcpy which does exactly this -- it accepts an argument of any type. You should be aware that you need to know the original type (i.e. typecast it to the type the data originally had) if you want to process the data passed "properly" (unless you don't do real processing like memcpy
and similar functions) as passing a void*
doesn't tell anything about the content -- it's just a pointer to some memory, without any information about its content, length or interpretation. Thus, your function needs to handle that by itself, probably with a different parameter that tells about the type. memcpy
, for example, requires a parameter passing the length of the data in bytes.
Your best bet is to use templating. You can use void pointers but that can lead to other problems if done incorrectly. Best thing to do is go HERE read the tutorial and try it out for yourself. You shouldn't have any problem understanding the concept of templates.
You might consider the printf approach. It passes in an argument, that identifies the type for the called function.
printf("%d", intvalue);
printf("%f", floatvalue);
printf("%s", stringvalue);
Here is a link that demonstrates how to implement a variable argument list.
If you don't want to pass a pointer, you could pass a union. Declare a union like a struct, but you can only use one member at a time. For example:
union foo {
char c;
int i;
}
struct foo f;
f.c = 'd';
function (f);
f.i = 23;
function(f);
int function(union foo f)
...
Remember that you can only use one field at a time, and if you set, say, f.c to something, the value of f.i is going to change in a potentially messy way. (I believe it's undefined behavior, but if a compiler ever does anything except byte-for-byte substitution it will fail to compile a whole lot of existing code.) Also, remember that the language provides no clue as to what field you last changed, so it's up to you to keep track of it somehow.
It isn't a very clean solution, but neither is the void *
one. You're trying to subvert
the type system, and you're not going to get a good solution.
it's been a while since i've done anything like this, so check the syntax.
To take off from Laura's answer, to make it more concise:
// the enum:
enum types{ int_val, char_val, float_val };
// the functions
int (*funcArr[3])(void*) = {NULL};
int to_do_if_int(void* input)
{
return 0;
}
int to_do_if_char(void* input)
{
return 0;
}
int to_do_if_float(void* input)
{
return 0;
}
void initializer()
{
funcArr[int_val] = &to_do_if_int;
funcArr[char_val] = &to_do_if_char;
funcArr[float_val] = &to_do_if_float;
}
int parse(void *arg, enum_type arg_type){
if (arg == NULL) return -1;
(*funcArr[arg_type])(arg);
return something;
}