I have seen a lot of C code using pointers to functions with an empty parameter list so that they can be used to call functions with different prototypes without a cast, so long as the return type is the same.
For example:
#include <stdio.h>
typedef void (*func_returning_void) ();
void empty_args ()
{
printf("empty args\n");
}
void zero_args (void)
{
printf("zero args\n");
}
void one_int_arg (int arg)
{
printf("one arg: %d\n", arg);
}
void two_string_args (const char *arg1, const char *arg2)
{
printf("two args: %s %s\n", arg1, arg2);
}
int main (void)
{
func_returning_void funcptr;
funcptr = empty_args;
funcptr();
funcptr = zero_args;
funcptr();
funcptr = one_int_arg;
funcptr(1);
funcptr = two_string_args;
funcptr("one", "two");
}
So long as arguments' number and types match the parameter list of the function being called, is this technique well-defined, or does it rely on undefined behavior ?
Note: I know that the other way around is undefined behavior, because in a function definition, the empty parameter list ()
has the same meaning as (void)
i.e. exactly zero arguments; as the C standard states:
"An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters."
void empty_params() {}
int main (void)
{
void (*funcptr) (int) = empty_params; // UB
funcptr(1234);
}