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

functions that return pointer to function

P: n/a
I have some code where there are a set of functions that return
pointers to each other. I'm having a bit of a hard time figuring out
the correct type to use to do that.

The code below works but I'm defining the functions as void*, and then
casting when I use them. This code is going into a general purpose
framework, and it would be much nicer if the user didn't need to do
any casting.

Can someone tell me how to set up those typedefs so that the casting
done in main is not required?

Thanks,
Mike

=================================
#include <stdio.h>

typedef void* p_t;
typedef void (*pf_t)(void);
typedef pf_t (*ppf_t)(void);

p_t f1(void);
p_t f2(void);

p_t f1(void)
{
printf("func1\n");
return f2;
}
p_t f2(void)
{
printf("func2\n");
return f1;
}

int main (void)
{
ppf_t var;

var = (ppf_t)f1;
var = (ppf_t)var();
var = (ppf_t)var();
var = (ppf_t)var();

return 0;
}
=================================

The output is:
func1
func2
func1

Mar 4 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
ms****@linuxmail.org schrieb:
I have some code where there are a set of functions that return
pointers to each other. I'm having a bit of a hard time figuring out
the correct type to use to do that.
There is none. At least not in portable C.
For objects, you have void * as the pointer type every object pointer
can be converted to or from.
For functions, there is not "generic function pointer type". Using
void * is not guaranteed to work -- there is no implicit conversion
specified, so void * may not be able to represent function pointers
(e.g. if program and data reside in different memory areas).
The code below works but I'm defining the functions as void*, and then
casting when I use them. This code is going into a general purpose
framework, and it would be much nicer if the user didn't need to do
any casting.
Well, having to cast outside of the argument lists of variable
argument functions or functions without prototypes usually
indicates that you are doing something wrong.
Can someone tell me how to set up those typedefs so that the casting
done in main is not required?
No. Start at f1. f1 returns a pointer to the type of f2.
f2 returns the type of f1, i.e. a pointer to a function
returning the type of f2, ....
The only answer is a generic function pointer type, which
C does not have.

So, the only thing you can do portably is

#include <stdio.h>

typedef void *(*pf_t)(void);
typedef pf_t (*ppf_t)(void);

void * f1(void);

pf_t f2(void);

void * f1(void)
{
static long data;
printf("func1\n");
return &data;
}

pf_t f2(void)
{
printf("func2\n");
return &f1;
}

int main (void)
{
pf_t var1;
ppf_t var2;

var2 = f2;
var1 = var2();
printf("%p\n", var1());

return 0;
}

which is not what you want. =================================
#include <stdio.h>

typedef void* p_t;
Note: Sometimes, one sees
typedef void *(*p_t)();
or
typedef int (*p_t)();
as stand-in for a generic function pointer type.
It does not make the casts unnecessary but "is
at least a function pointer type".
typedef void (*pf_t)(void);
typedef pf_t (*ppf_t)(void);

p_t f1(void);
p_t f2(void);

p_t f1(void)
{
printf("func1\n");
return f2;
Every standard conforming compiler worth its salt will
warn you in this place. Keep the warning -- when migrating
to another compiler, operating system, or platform, it
reminds you to rethink your choice of p_t.
}
p_t f2(void)
{
printf("func2\n");
return f1;
}

int main (void)
{
ppf_t var;

var = (ppf_t)f1;
var = (ppf_t)var();
var = (ppf_t)var();
var = (ppf_t)var();

return 0;
}
=================================

The output is:
func1
func2
func1


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Mar 5 '06 #2

P: n/a

<ms****@linuxmail.org> wrote in message
news:11**********************@v46g2000cwv.googlegr oups.com...
I have some code where there are a set of functions that return
pointers to each other. I'm having a bit of a hard time figuring out
the correct type to use to do that.

The code below works but I'm defining the functions as void*, and then
casting when I use them. This code is going into a general purpose
framework, and it would be much nicer if the user didn't need to do
any casting.

Can someone tell me how to set up those typedefs so that the casting
done in main is not required?


This eliminates your casting. If it doesn't work with your compiler, see
Michael Mair's comments. I commentd out your original code with '#if 0'
'#endif'. Hint: compare the new pf_t with f1.

#include <stdio.h>

typedef void* p_t;
#if 0
typedef void (*pf_t)(void);
typedef pf_t (*ppf_t)(void);
#endif
typedef p_t (*pf_t)(void);

p_t f1(void);
p_t f2(void);

p_t f1(void)
{
printf("func1\n");
return f2;
}
p_t f2(void)
{
printf("func2\n");
return f1;
}

int main (void)
{
#if 0
ppf_t var;
#endif
pf_t var;

#if 0
var = (ppf_t)f1;
var = (ppf_t)var();
var = (ppf_t)var();
var = (ppf_t)var();
#endif
var = f1;
var = var();
var = var();
var = var();

return 0;
}
Rod Pemberton
Mar 5 '06 #3

P: n/a
>ms****@linuxmail.org schrieb:
I have some code where there are a set of functions that return
pointers to each other. I'm having a bit of a hard time figuring out
the correct type to use to do that.

In article <46************@individual.net>
Michael Mair <Mi**********@invalid.invalid> wrote:There is none. At least not in portable C.
There is no *direct* type, at least.

[snippage]
Start at f1. f1 returns a pointer to the type of f2.
f2 returns the type of f1, i.e. a pointer to a function
returning the type of f2, ....
The only answer is a generic function pointer type, which
C does not have.


Alternatively, you can wrap these things up inside "struct"s:

#include <stdio.h>

struct func {
struct func (*fp)(void);
};

struct func f1(void), f2(void);

struct func f1(void) {
struct func val;

puts("in f1");
val.fp = f2;
return val;
}

struct func f2(void) {
struct func val;

puts("in f2");
val.fp = f1;
return val;
}

int main(void) {
struct func f = { f1 };
int i;

for (i = 0; i < 5; i++)
f = f.fp();
return 0;
}

(or, do the same as the above but change "struct func" to
"struct func *" in all the obvious places, make f point to one,
and make the "val"s in each function static and return their
addresses; or pass a pointer to the "struct func" object to
each function and have it update f->fp; etc.).

The OP's method (having functions return "pointer to function (args)
returning T" for some valid type T, then using casting to make it all
work out) is OK, if a bit error-prone. In particular, casting tends
to make the compiler shut up even if the cast is wrong, so you have
to very sure that every cast is really correct.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Mar 5 '06 #4

P: n/a
Thank you everybody. This has been very helpfull.

Mike

Mar 8 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.