Janet said:
Could you say what you mean by "no defined cast to pointer to
function"?
He means that converting between what is often called a "data pointer"
(a pointer to any arithmetic or aggregate type) and a function pointer
is not permitted by the standard. Such a conversion is often provided
as an extension, but it is not wise to rely on it.
Maybe I should elaborate on the question. Basically I'm coming from JAVA
and trying to implement polymorphism via an array of function pointers.
The functions all take the same arguments, but they have different
return values, e.g.
int f1(int x, int y);
double f2(int x, int y);
etc.
As I'm never actually going to need the return value I was hoping to use
a void* instead of actual function pointers to let me ignore the
difference between the return types of the functions. Is that going to
work?
No, not a void * because of the above.
You may, however, convert between and two function pointer types but
at the point of making the call, the type of the pointer used must
match that of the function being called.
You can legally do this:
typedef void generic_function(int, int);
generic_function *fp1 = (generic_function *)f1;
provided that when you call the pointer to function you convert the
pointer:
((int (*)(int, int))fp1)(4, 2);
This is, of course, rather ugly (some typedefs help) but, worse,
you've got to know the type at the point of call and that can defeat
the purpose.
So, to avoid this, you have to have the functions returning the same
type. You can do this by wrapping them as Malcolm McLean has
suggested. An alternative is to edit them so they all return a union
type which includes all the possible old return types. The down side
of this method is that you may have existing calls like:
int x = f1(2, 3);
that need to be changed to:
int x = f1(2, 3).int_value;
but you will not have a whole bunch of extra wrappers. Of course, if
you *really* don't need the return value, just loose it and make all the
function return void.
The union return is a royal pain in "old" C90. In C99 one has compound
literals and one can write:
typedef union value_t {
int int_value;
double double_value;
} value_t;
value_t f1(int x, int y) { return (value_t){ .int_value = x + y }; }
One of the best parts of C99 IMHO.