# Arbitrary Function Arrays

Discussion in 'C Programming' started by Randy Yates, Mar 11, 2005.

1. ### Randy YatesGuest

Hi,

We know we can build arrays of variables of the same type and arrays
of functions of the same "type" (i.e., same return value and same
parameters), but is there a way to automate the calling of a sequence
of functions with arbitrary return types and/or parameters?
--
Randy Yates
Sony Ericsson Mobile Communications
Research Triangle Park, NC, USA
, 919-472-1124

Randy Yates, Mar 11, 2005

2. ### Eric SosmanGuest

Randy Yates wrote:

> Hi,
>
> We know we can build arrays of variables of the same type and arrays
> of functions of the same "type" (i.e., same return value and same
> parameters), but is there a way to automate the calling of a sequence
> of functions with arbitrary return types and/or parameters?

Functions cannot be array elements: they are not data
objects, and they do not have size. You are probably thinking
of an array of pointers to functions; pointers are data objects,
have size, and can be elements in an array.

Next, all the elements in an array of function pointers
must have the same type. This is the same as for any other
array: you can't have an array whose [0] element is an `int',
whose [1] element is a `double', and whose [2] element is a
`const struct muggle_descriptor*'. The pointers may, however,
have been converted from disparate types to a common type by
casting -- of course, they've got to be converted back to match
the actual called function at the point of the call.

However, the function call construct in C is "static" in
the sense that the type of the return value and the number and
types of the arguments are fixed at compile time. Even for a
variadic function, which can be called with differing argument
lists at different points in the program, the circumstances of
any particular call in the source are unchangeable. When you
write `foo(x,y)' the call passes exactly two arguments of
exactly the same type, every time you execute it. There's no
way to get rid of an argument, add an argument, or change the
type of an argument other than by editing and recompiling.

I've encountered two approaches to working around this
inflexibility. One is to enumerate all the function types
of interest, and to use a big `switch' or something of the
kind to choose between the appropriate calls:

fptr = ...;
switch (ftype) {
case INT_VOID:
intres = ((int(*)(void))f)();
break;
case DBL_INT:
dblres = ((double(*)(int))f)(42);
break;
...

This becomes messy unless the number of different function
signatures is quite small.

A second approach is to use "wrapper" functions. You use
an array of `void*' or an array of unions or some such to hold
the actual arguments -- you can build the array at run-time --
and pass it to the wrapper. The wrapper plucks the appropriate
arguments from the array, passes them to the target function,
and returns the result. As a variation, you can use one wrapper
for each different target function signature, passing a pointer
to the target function along with the array of "anonymous"
arguments.

--
Eric Sosman
lid

Eric Sosman, Mar 11, 2005

3. ### Daniel HaudeGuest

On 11 Mar 2005 08:14:44 -0500,
Randy Yates <> wrote
in Msg. <>

> We know we can build arrays of variables of the same type and arrays
> of functions of the same "type" (i.e., same return value and same
> parameters), but is there a way to automate the calling of a sequence
> of functions with arbitrary return types and/or parameters?

To the actual question, see Eric's exhaustive posting. I'd just like to
ask: If it was possible to construct an array of pointers to functions
with different signatures, what good would it do you? I'm just curious
about what you're trying to accomplish here.

--Daniel

Daniel Haude, Mar 11, 2005
4. ### Tommy ReynoldsGuest

On Fri, 11 Mar 2005 08:14:44 -0500, Randy Yates wrote:

> We know we can build arrays of variables of the same type and arrays of
> functions of the same "type" (i.e., same return value and same
> parameters), but is there a way to automate the calling of a sequence of
> functions with arbitrary return types and/or parameters?

C doesn't let you overload function definitions. Maybe something
like this is what you're looking for:

typedef struct arbfunc_s {
union {
int (*i)(.....);
char * (*c)(.....);
} u;
int kind;
} arbfunc_t;

arbfunct_t actions[ 100 ] = {
{ intfunc, IS_INT },
{ anotherIntFunc, IS_INT },
{ mychar, IS_CHAR }
{ 0 }
};

....
arbfunc_t * ap = actions;
....
for( ap = actions; ap->kind > 0; ++ap ) {
switch( ap->kind ) {
case IS_INT: results = (ap->u.i)(....); break;
case IS_CHAR: results = (ap->u.c)(...); break;
}
}

depending on what you're doing, this may work.

Cheers

Tommy Reynolds, Mar 11, 2005