By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,784 Members | 3,274 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,784 IT Pros & Developers. It's quick & easy.

function prototypes and function addresses

P: n/a
Hi,
is it possible to write two functions which both require a function as
an argument and both being able to use the other function as an
argument? Afaik the address of a function is not known upon declaration
but only once its defined.

Thanks
Jan 9 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
In article <47***********************@newsspool1.arcor-online.net>,
Syren Baran <sy***@gmx.dewrote:
>is it possible to write two functions which both require a function as
an argument and both being able to use the other function as an
argument?
Yes.
>Afaik the address of a function is not known upon declaration
but only once its defined.
The address of a function is not known until link time, or
possibly not until run time.

But that doesn't really matter, because you asked about being
able to use the other function as an argument, which is something
that happens at run time, not at compile time. You did not ask
that each has static calls to each other.

For example,

int fun1(int (*auxfun)()) { return (auxfun == NULL) ? 5 : 17 * auxfun(NULL); }

int fun2(int (*auxfun)()) { return (auxfun == NULL) ? 42 : 9 - auxfun(NULL); }

int fun3(void) { return fun1(fun2) + fun2(fun1); }
--
"There are some ideas so wrong that only a very intelligent person
could believe in them." -- George Orwell
Jan 9 '08 #2

P: n/a
On Jan 9, 7:43 pm, Syren Baran <sy...@gmx.dewrote:
Hi,
is it possible to write two functions which both require a function as
an argument and both being able to use the other function as an
argument? Afaik the address of a function is not known upon declaration
but only once its defined.
It is not about the address, but the prototype of the function.
After a while you will realise it is impossible to write two functions
'foo' and 'bar' that work like this:
--
foo() { bar(foo); }
bar() { foo(bar); }
--
Types/arguments are missing on purpose because as I said it is not
possible to define such functions.
Jan 9 '08 #3

P: n/a
On Wed, 09 Jan 2008 17:53:22 +0000, Walter Roberson wrote:
int fun1(int (*auxfun)()) { return (auxfun == NULL) ? 5 : 17 *
auxfun(NULL); }

int fun2(int (*auxfun)()) { return (auxfun == NULL) ? 42 : 9 -
auxfun(NULL); }

int fun3(void) { return fun1(fun2) + fun2(fun1); }
Whether NULL is defined as an integer or as a pointer, it won't be a
function pointer, and since auxfun lacks a prototype, it won't be
implicitly converted to one either. This is one of the situations where
you should use a cast.

int fun1(int (*auxfun)()) {
return (auxfun == NULL) ? 5 : 17 * auxfun((int(*)())NULL);
}

int fun2(int (*auxfun)()) {
return (auxfun == NULL) ? 42 : 9 - auxfun((int(*)())NULL);
}

int fun3(void) { return fun1(fun2) + fun2(fun1); }

You could also expand your function pointer declaration:

int fun1(int (*auxfun)(int (*)())) {
return (auxfun == NULL) ? 5 : 17 * auxfun(NULL);
}

int fun2(int (*auxfun)(int (*)())) {
return (auxfun == NULL) ? 42 : 9 - auxfun(NULL);
}

int fun3(void) { return fun1(fun2) + fun2(fun1); }

but the cast is just as easy to type and easier to read, in my opinion.
Jan 9 '08 #4

P: n/a
Walter Roberson schrieb:
>Afaik the address of a function is not known upon declaration
but only once its defined.

The address of a function is not known until link time, or
possibly not until run time.

But that doesn't really matter, because you asked about being
able to use the other function as an argument, which is something
that happens at run time, not at compile time. You did not ask
that each has static calls to each other.
Thanks, that helps. Was unsure about when the address is calculated.
In other words, if something like
declare function1
use function1 as an argument
define function1
doesnt work, the problem lies elsewhere.
>
For example,
Neat :)
Jan 9 '08 #5

P: n/a
Syren Baran wrote:
Hi,
is it possible to write two functions which both require a function as
an argument and both being able to use the other function as an
argument? Afaik the address of a function is not known upon declaration
but only once its defined.
No, functions are not allowed as arguments to C functions. The result
of a function call is a value that can be passed as an argument.
Function pointers can be passed as an argument. But functions
themselves cannot. If it seems otherwise, it's probably because a
function name is automatically converted into a pointer to the named
function in most contexts. If you're talking about function pointers,
then yes, it is possible.

The tricky detail is declaring the types in the function prototypes.
The problem, as you'll find out if you try it, is that fully declaring
the argument types requires infinite recursion. The solution is, at
some point, to take advantage of the fact that C doesn't require you
to declare the argument type - instead of using a function prototype,
use an old-style function declaration that leaves the argument list
unspecified.

It's very easy, when writing code like this, to produce infinitely
recursive function calls. Remember to insert something to prevent
infinite recursion. In the following rather silly code, 'count' serves
that purpose.

#include <stdio.h>
int func1(unsigned count, int(*f)())
{
printf("func1 +%ux\n", count);
if(count && f != NULL)
count = f(count-1, f);
printf("func1 -%ux\n", count);
return count;
}

int func2(unsigned count, int(*f)())
{
printf("func2 +%ux\n", count);
if(count>0 && f!=NULL)
count = f(count-1,func1);
printf("func2 -%ux\n", count);
return count;
}

int main(int argc, char *argv[])
{
func2(argc, func2);
return 0;
}

Note: if you want func1() to be able to refer to func2 by name the
same way that func2 refers to func1, you'll have to forward declare
func2 before defining func1.
Jan 9 '08 #6

P: n/a
vipps...@gmail.com wrote:
On Jan 9, 7:43 pm, Syren Baran <sy...@gmx.dewrote:
Hi,
is it possible to write two functions which both require a function as
an argument and both being able to use the other function as an
argument? Afaik the address of a function is not known upon declaration
but only once its defined.
It is not about the address, but the prototype of the function.
After a while you will realise it is impossible to write two functions
'foo' and 'bar' that work like this:
--
foo() { bar(foo); }
bar() { foo(bar); }
--
Types/arguments are missing on purpose because as I said it is not
possible to define such functions.
void foo(void(*)());
void bar(void(*)());

void foo(void(*f)()) {bar(foo);}
void bar(void(*f)()) {foo(bar);}
Works for me. It's infinitely recursive, of course, but I assume that
you didn't mean your example to be taken literally; in any useful
context, the would be some mechanism to terminate the recursion before
it became infinite.
Jan 9 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.