Reputation: 45
Normally, in C99, you can achieve function overloading (number of arguments, not type overloading) by using VA_ARGS and some kind of macro trick like:
#define THIRD_PARAMETER(_1,_2,_3,...) _3
#define NOTHING
for example:
void pr1(int x);
void pr2(int x, int y);
#define pr(...) THIRD_PARAMETER(__VA_ARGS__, pr2, pr1, NOTHING)(__VA_ARGS__)
(I add NOTHING
macro so that C99 won't complain about zero argument passed to ...
when I call pr(100)
to print 100
, I want my program is fully compatible with C99)
But the problem is: pr is not a function, so it can't be assigned to a function pointer inside a struct :
// this is a dynamic array
struct array {
// ...
void (*insert)(struct array * a, ...);
// ...
};
suppose i have 3 versions of insert: single_insert, multiple_insert, range_insert, which have 3,4,5 arguments respectively. How can I implement function overloading (number of arguments) inside a C99 struct ? is it possible ?
Upvotes: 0
Views: 184
Reputation: 60097
You can give the .insert
function pointer an arbitrary type (if you use something like void (*)()
, then void-returing functions that take arguments that aren't short or variadic will convert to that pointer type implicitly, but that isn't essential) and then have an INSERT(&myarray, ...)
macro that'll count the arguments, cast .insert
to the appropriate type according to the count, and then call it.
Upvotes: 0
Reputation: 180978
suppose i have 3 versions of insert: single_insert, multiple_insert, range_insert, which have 3,4,5 arguments respectively. How can I implement function overloading (number of arguments) inside a C99 struct ? is it possible ?
You can declare a function pointer that does not provide a prototype, which would therefore be compatible with functions with different numbers and even different types of arguments:
void (*insert)();
But whatever function that points to is the one that will be called through such a pointer -- you will not get selection of different functions based on the argument list. Also, the arguments will be subject to the default argument promotions, and the promoted arguments must agree in type and number with the actual function parameters.
If your pointer declaration does provide a prototype, and you call the pointed-to function through it, then that function must have a compatible signature, as "compatible" is defined in the language specifications. In particular, variadic and non-variadic function declarations are not compatible with each other, so your idea to declare the pointer with a variadic prototype is non-conforming.
Thus, it really hasn't anything to do with structures. Rather, the issue is function pointers. You can apply a macro trick such as you describe to select among several function pointers, or you can write a variadic wrapper function that performs such a selection, but you cannot encode such a selection into the pointer itself.
Upvotes: 2