Duy
Duy

Reputation: 45

Function overloading inside a C99 struct

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

Answers (2)

Petr Skocik
Petr Skocik

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

John Bollinger
John Bollinger

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

Related Questions