473,473 Members | 1,782 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

functions that return pointer to function

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
4 6927
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

<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
>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 (40°39.22'N, 111°50.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
Thank you everybody. This has been very helpfull.

Mike

Mar 8 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Nolan Martin | last post by:
is a static functions address constant? ie.. static void func(); write_to_file(&func); Restart program... static void func(); void (*funcPtr) ();
2
by: Thomas Matthews | last post by:
Hi, I would like to create a table (or vector) of pointers to templated functions. 1. How do I declare a typedef of a pointer to a templated function? For example, I have some functions...
6
by: Melkor Ainur | last post by:
Hello, I'm attempting to build an interpreter for a pascal-like language. Currently, I don't generate any assembly. Instead, I just build an abstract syntax tree representing what I've parsed...
10
by: Pete | last post by:
Can someone please help, I'm trying to pass an array to a function, do some operation on that array, then return it for further use. The errors I am getting for the following code are, differences...
9
by: Mikhail Teterin | last post by:
Hello! I'd like to have a variable of a pointer-to-function type. The two possible values are of type (*)(FILE *) and (*)(void *). For example: getter = straight ? fgetc : gzgetc; nextchar...
4
by: Jonathan Burd | last post by:
Greetings everyone, Here is a random string generator I wrote for an application and I'm wondering about the thread-safety of this function. I was told using static and global variables cause...
23
by: Timothy Madden | last post by:
Hello all. I program C++ since a lot of time now and I still don't know this simple thing: what's the problem with local functions so they are not part of C++ ? There surely are many people...
60
by: jacob navia | last post by:
Gnu C features some interesting extensions, among others compound statements that return a value. For instance: ({ int y = foo(); int z; if (y>0) z = y; else z=-y; z; }) A block enclosed by...
5
by: Tim Frink | last post by:
Hi, I'm experimenting with function pointers and found two questions. Let's assume this code: 1 #include <iostream> 2 class A; 3 4 //////////////////////////////////////////// 5 class B
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.