Pointer to function

J

Jim Ford

I wonder if the following is possible:

I would like to have a function with, say, three arguments. The
first two would be int, whereas the third one would be a pointer to a
generic function. By this I mean a function that can take any number of
arguments, of any type, and that can return anything, including void.

Is this allowed under ANSI C?
 
M

Mark A. Odell

I wonder if the following is possible:

I would like to have a function with, say, three arguments. The
first two would be int, whereas the third one would be a pointer to a
generic function. By this I mean a function that can take any number of
arguments, of any type, and that can return anything, including void.

Is this allowed under ANSI C?

Sure.

int func(int a, int b, void (*pFunc)(char *pFmt, ...));

int main(void)
{
func(1, 2, printf);

return 0;
}
 
K

Kevin Bracey

In message <[email protected]>
Jim Ford said:
I wonder if the following is possible:

I would like to have a function with, say, three arguments. The
first two would be int, whereas the third one would be a pointer to a
generic function. By this I mean a function that can take any number of
arguments, of any type, and that can return anything, including void.

Is this allowed under ANSI C?

Not straightforwardly. You can leave the arguments unspecified, but that's
deprecated, and precludes any arguments actually being "narrow" types (ie
char, short, float). You have to specify a specific return type.

However, the standard says that you can store any function pointer value
in a function pointer of another type without loss - basically the same
guarantee as given for void * storing object pointers. So you could fudge it
thus, quite legally:

typedef void (*GenericFnPtr)(void); // any function ptr type would do

void jims_func(int a, int b, GenericFnPtr fn);

int myfunc(int a);

jims_func(1, 2, (GenericFnPtr) myfunc);

void jims_func(int a, int b, GenericFnPtr fn)
{
int n;
switch (a)
{
case 1: n = (((int (*)(int))p)(b);
break;
...
}
...
}

You will have to do all the icky casting, but maybe it could be tidied with
some more typedefs and/or macros. And obviously you'll have to know what
the actual type of the stored function actually is, so you can cast it back
to the correct type before use.
 
D

Dan Pop

In said:
Sure.

int func(int a, int b, void (*pFunc)(char *pFmt, ...));

Are you sure you have declared pFunc as a pointer to a function that can
take *any* number of arguments, of any type and return *anything*?

The only bit that's actually impossible is returning anything. A function
declaration must specify a return type and there is no way around. The
workaround is to make the candidate functions return a union containing
all the types of interest.

The any number of arguments of any type can be easily obtained by not
declaring an argument list at all. There are a couple of limitations,
however:

1. The function call must be compatible with the actual definition of the
called function. The compiler cannot check this, but any mismatch
results in undefined behaviour.

2. The function parameters must not have types that are subject to the
default argument promotions: because the function pointer declaration
doesn't include a prototype, the default argument promotions cannot
be avoided.

With these in mind, the prototype of the OP's function is:

union omnia;
int func(int a, int b, union omnia (*pFunc)());

Dan
 
M

Mark A. Odell

Are you sure you have declared pFunc as a pointer to a function that can
take *any* number of arguments, of any type and return *anything*?

No, I guess not. I can't return anything just one type.
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) wrote in

No, I guess not. I can't return anything just one type.

And you can't call it with no arguments or with a single argument of type
int, and so on.

Dan
 
M

Mark A. Odell

And you can't call it with no arguments or with a single argument of
type int, and so on.

This is turning out horribly, I've missed the mark on all counts.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,104
Messages
2,570,643
Members
47,247
Latest member
youngcoin

Latest Threads

Top