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

Home Posts Topics Members FAQ

Pointer to functions

I know that a variable (void *) is guaranteed to be able to store any
pointer and to allow conversion back to the original pointer.

I think, then, that I can store a pointer to a function in a (void *)
variable and then convert it back to the original type and use it as a
funtion.

The question is: am I correct or there might be situations where this
could fail?

To clarify, here is an example of what I'm trying to do:

/* Prototypes of functions that are defined somewhere */
int f1(int x);
void f2(int a, int b);

/* Variables of type "pointers to functions" */
int (*fa)(int);
void (*fb)(int, int);

/* An array of generic pointers */
void *fun_vec[2];

..... /* later in the code ... */
fun_vec[0] = f1; /* store pointers to f1 and f1 */
fun_vec[1] = f2; /* into void * */

..... /* even later ... */
fa = fun_vec[0]; /* get them back as pointers */
fb = fun_vec[1]; /* to functions */

fb(2,fa(3)); /* use the functions */

....

Jun 27 '08 #1
14 1396
Remo D. <rdwrote:
I know that a variable (void *) is guaranteed to be able to store any
pointer and to allow conversion back to the original pointer.
I think, then, that I can store a pointer to a function in a (void *)
variable and then convert it back to the original type and use it as a
funtion.
The question is: am I correct or there might be situations where this
could fail?
Unfortunately, function pointers aren't covered by the C standard
as being convertible to a void pointer and back. There seem to be
some architectures where this leads to problems. On the other hand
in many cases you probably will be able to do so (e.g. on POSIX
compliant systems this has to work or e.g. the dlopen() couldn't
be used).
To clarify, here is an example of what I'm trying to do:
/* Prototypes of functions that are defined somewhere */
int f1(int x);
void f2(int a, int b);
/* Variables of type "pointers to functions" */
int (*fa)(int);
void (*fb)(int, int);
/* An array of generic pointers */
void *fun_vec[2];
.... /* later in the code ... */
fun_vec[0] = f1; /* store pointers to f1 and f1 */
fun_vec[1] = f2; /* into void * */
.... /* even later ... */
fa = fun_vec[0]; /* get them back as pointers */
fb = fun_vec[1]; /* to functions */
fb(2,fa(3)); /* use the functions */
With most systems you should be fine doing it that way. Note that
you also can write the last e.g. as

fun_vec[ 1 ]( 2, fun_vec[ 0 ]( 3 ) );

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jun 27 '08 #2
Jens Thoms Toerring ha scritto:
>
Unfortunately, function pointers aren't covered by the C standard
as being convertible to a void pointer and back. There seem to be
some architectures where this leads to problems. On the other hand
in many cases you probably will be able to do so (e.g. on POSIX
compliant systems this has to work or e.g. the dlopen() couldn't
be used).
Thanks Jens! I found a draft of the C standard (N869) on the internet
and, as you said, there's no mention of pointers to functions being
convertible to void *.

However, in section 6.3.2.3 paragraph 8 they say:
>A pointer to a function of one type may be converted to
a pointer to a function of another type and back again;
the result shall compare equal to the original pointer.
If a converted pointer is used to call a function whose
type is not compatible with the pointed-to type, the
behavior is undefined.
So, if I would declare an array of function pointers, should it be safer?

/* array of 2 pointers to function returning int */
int (*fun_vec[2])();

Once I convert them to the appropriate function type, it should work (if
I read the standard correctly).

As you rightly pointed out it should also work as long as I use them
correctly (I would expect compiler warnings, though).

R:D
Jun 27 '08 #3
On Jun 19, 5:40 pm, "Remo D." <rdwrote:
I know that a variable (void *) is guaranteed to be able to store any
pointer and to allow conversion back to the original pointer.
It's a common extension to do so, (see Annex G ISO 9899:1999) but
conforming programs should not rely on that.
I think, then, that I can store a pointer to a function in a (void *)
variable and then convert it back to the original type and use it as a
funtion.
Not allowed by ISO C.
You are, however, allowed to convert any function pointer to any other
function pointer and back, and get the same result.
The question is: am I correct or there might be situations where this
could fail?
Yes, for example if a function pointer is not really a pointer, or
cannot be represented by void *, etc.
To clarify, here is an example of what I'm trying to do:

/* Prototypes of functions that are defined somewhere */
int f1(int x);
void f2(int a, int b);

/* Variables of type "pointers to functions" */
int (*fa)(int);
void (*fb)(int, int);

/* An array of generic pointers */
void *fun_vec[2];

.... /* later in the code ... */
fun_vec[0] = f1; /* store pointers to f1 and f1 */
fun_vec[1] = f2; /* into void * */

.... /* even later ... */
fa = fun_vec[0]; /* get them back as pointers */
fb = fun_vec[1]; /* to functions */

fb(2,fa(3)); /* use the functions */
Here's the fix:

int f1(int);
void f2(int, int);

int (*fa)(int);
void (*fb)(int, int);

fa = f1;
fb = f2;

/* the type of function pointer really doesn't matter, I use void (*)
() */
void (*fun_vec[])() = { fa, fb }; /* I think a cast is not needed, but
I'm not sure, anyone can help? */

/* ... later ... */

fa = fun_vec[0];
fb = fun_vec[1];

Jun 27 '08 #4
On Jun 19, 6:57 pm, vipps...@gmail.com wrote:
On Jun 19, 5:40 pm, "Remo D." <rdwrote:I know that a variable (void *) is guaranteed to be able to store any
pointer and to allow conversion back to the original pointer.

It's a common extension to do so, (see Annex G ISO 9899:1999) but
Correction: Annex J, J.5

Jun 27 '08 #5
Remo D. <rdwrote:
Jens Thoms Toerring ha scritto:

Unfortunately, function pointers aren't covered by the C standard
as being convertible to a void pointer and back. There seem to be
some architectures where this leads to problems. On the other hand
in many cases you probably will be able to do so (e.g. on POSIX
compliant systems this has to work or e.g. the dlopen() couldn't
be used).
Thanks Jens! I found a draft of the C standard (N869) on the internet
and, as you said, there's no mention of pointers to functions being
convertible to void *.
However, in section 6.3.2.3 paragraph 8 they say:
>A pointer to a function of one type may be converted to
>a pointer to a function of another type and back again;
>the result shall compare equal to the original pointer.
>If a converted pointer is used to call a function whose
>type is not compatible with the pointed-to type, the
>behavior is undefined.
So, if I would declare an array of function pointers, should it be safer?
/* array of 2 pointers to function returning int */
int (*fun_vec[2])();
Once I convert them to the appropriate function type, it should work (if
I read the standard correctly).
Yes, that's also how I would understand it.

So

fun_vec[ 1 ]( 2, fun_vec[ 0 ]( 3 ) );

would be problematic, to say the least (and what I wrote in my last
post was wrong since there they where void pointers...), while

fa = fun_vec[0]; /* get them back as pointers */
fb = fun_vec[1]; /* to functions */

fb(2,fa(3)); /* use the functions */

is ok.
As you rightly pointed out it should also work as long as I use them
correctly (I would expect compiler warnings, though).
You can always cast them to the correct type to make the compiler
happy. Using your example:

fun_vec[0] = f1;
fun_vec[1] = (int (*)()) f2;

fa = fun_vec[0];
fb = (void (*)()) fun_vec[1];

or even

fa = (int (*)(int)) fun_vec[0];
fb = (void (*)(int, int)) fun_vec[1];

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jun 27 '08 #6
vi******@gmail.com ha scritto:
>I think, then, that I can store a pointer to a function in a (void *)
variable and then convert it back to the original type and use it as a
funtion.
Not allowed by ISO C.
You are, however, allowed to convert any function pointer to any other
function pointer and back, and get the same result.
[...]
Here's the fix:
[...]
void (*fun_vec[])() = { fa, fb }; /* I think a cast is not needed, but
Thanks vippstar. I'll use an array of function pointers.

Remo
Jun 27 '08 #7
Jens Thoms Toerring ha scritto:
Remo D. <rdwrote:
>As you rightly pointed out it should also work as long as I use them
correctly (I would expect compiler warnings, though).

You can always cast them to the correct type to make the compiler
happy. Using your example:

fun_vec[0] = f1;
fun_vec[1] = (int (*)()) f2;

fa = fun_vec[0];
fb = (void (*)()) fun_vec[1];

or even

fa = (int (*)(int)) fun_vec[0];
fb = (void (*)(int, int)) fun_vec[1];
Thanks for the advice, Jens.

I'll use an array of pointer to functions and will cast appropriately
when assigning back to variable.

Very useful discussion! (at least for me :) )

RD
Jun 27 '08 #8
Remo D. wrote:
I know that a variable (void *) is guaranteed to be able to store any
pointer and to allow conversion back to the original pointer.
A pointer-to-void is only guaranteed to be able to hold any
pointer-to-object. It is not guaranteed to be able to hold any
pointer-to-function.

However, it is guaranteed that you can convert a pointer-to-function to
a different type of pointer-to-function and back. This seems to be good
enough for what you want.
I think, then, that I can store a pointer to a function in a (void *)
variable and then convert it back to the original type and use it as a
funtion.

The question is: am I correct or there might be situations where this
could fail?
It is allowed to fail, though I'm not sure there are any real-world
systems where it will. Still, one should avoid code that isn't
guaranteed to work when there's a reasonably clear alternative that is.

S
Jun 27 '08 #9
Stephen Sprunk wrote:
>
[Is void* <=funcptr conversion allowed?]
It is allowed to fail, though I'm not sure there are any real-world
systems where it will. [...]
I believe it produces a run-time error on IBM AS/400
(aka iSeries). Can anyone refute or confirm?

--
Er*********@sun.com
Jun 27 '08 #10
In article <q2****************@nlpi069.nbdc.sbc.com>
Stephen Sprunk <st*****@sprunk.orgwrote:
>[Using "void *" to hold function pointers] is allowed to fail,
though I'm not sure there are any real-world systems where it will.
There are at least two: old DOS-based PCs (when using some of the
"memory models", in this case, when using 16-bit data, 32-bit-code
models); and IBM AS/400 machines.
>Still, one should avoid code that isn't guaranteed to work when
there's a reasonably clear alternative that is.
Indeed. The methods described elsethread are probably *clearer*
than the version with plain "void *", at least once one gets past
the tricky concept of "array of pointer to function". (That is,
both methods are equally obscure if one does not understand the
concept in the first place, and "array of pointer to function"
has bizarre-looking syntax in C. These combine to make a fairly
large "mental digestion" step. Typedef aliases can help though.)
--
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: gmail (figure it out) http://web.torek.net/torek/index.html
Jun 27 '08 #11
"Remo D." <rdwrote:
Jens Thoms Toerring ha scritto:

Unfortunately, function pointers aren't covered by the C standard
as being convertible to a void pointer and back. There seem to be
some architectures where this leads to problems. On the other hand
in many cases you probably will be able to do so (e.g. on POSIX
compliant systems this has to work or e.g. the dlopen() couldn't
be used).

Thanks Jens! I found a draft of the C standard (N869) on the internet
and,
That is _very_ old. Search for n1256.pdf: it has the complete C99
Standard, plus TC 1 and 2, plus the last draft of TC 3.
as you said, there's no mention of pointers to functions being
convertible to void *.

However, in section 6.3.2.3 paragraph 8 they say:
>A pointer to a function of one type may be converted to
>a pointer to a function of another type and back again;
>the result shall compare equal to the original pointer.
So, if I would declare an array of function pointers, should it be safer?

/* array of 2 pointers to function returning int */
int (*fun_vec[2])();

Once I convert them to the appropriate function type, it should work (if
I read the standard correctly).
Yes. See also the FAQ: <http://c-faq.com/ptrs/generic.html>.

Richard
Jun 27 '08 #12
Richard Bos wrote:
"Remo D." <rdwrote:
>Jens Thoms Toerring ha scritto:
>>Unfortunately, function pointers aren't covered by the C standard
as being convertible to a void pointer and back. There seem to be
some architectures where this leads to problems. On the other hand
in many cases you probably will be able to do so (e.g. on POSIX
compliant systems this has to work or e.g. the dlopen() couldn't
be used).

Thanks Jens! I found a draft of the C standard (N869) on the internet

That is _very_ old. Search for n1256.pdf: it has the complete C99
Standard, plus TC 1 and 2, plus the last draft of TC 3.
However it has minimal differences from the actual standard. If
you want an edited text copy, quite suitable for quoting in
newsgroups, and easily searched with text processing software, see:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>

for a bzip2 compressed text version. There are no decent text
versions for anything later than N869.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #13
CBFalconer ha scritto:
Richard Bos wrote:
>"Remo D." <rdwrote:
>>I found a draft of the C standard (N869) on the internet
That is _very_ old. Search for n1256.pdf: it has the complete C99

However it has minimal differences from the actual standard. If
you want an edited text copy, quite suitable for quoting in
newsgroups, and easily searched with text processing software, see:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>
Thanks for pointing me in the right direction. I've saved both the
n1256.pdf and the n869.txt. They'll make my life easier.

And shame on me for not having gone trhough the FAQ before posting!

R.D
Jun 27 '08 #14
"Remo D." <rdwrites:
CBFalconer ha scritto:
>Richard Bos wrote:
>>"Remo D." <rdwrote:
I found a draft of the C standard (N869) on the internet
That is _very_ old. Search for n1256.pdf: it has the complete C99

However it has minimal differences from the actual standard. If
you want an edited text copy, quite suitable for quoting in
newsgroups, and easily searched with text processing software, see:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>

Thanks for pointing me in the right direction. I've saved both the
n1256.pdf and the n869.txt. They'll make my life easier.

And shame on me for not having gone trhough the FAQ before posting!

R.D
Please note that Falconer's copy is out of date and he is constantly
reminded of that but refuses to stop pimping it out. He seems unaware
that you can search and copy from a pdf too. One can only guess at his
motives.
Jun 27 '08 #15

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

Similar topics

9
2501
by: iceColdFire | last post by:
HI, I have a function as void f(int p) { return p++; } now I have created a function pointer as
4
6931
by: msolem | last post by:
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...
14
1931
by: Bryan Parkoff | last post by:
Do you know that current C++ Compiler limits to 64KB segments in source code? It is good news that Microsoft Visual C++ 2005 has expanded to 4GB segments in source code. 4GB segment is ideal for...
11
2698
by: Felix Kater | last post by:
Hi, I can compile and run this code (see below) which twice calls the function f, first with too less, second with too much arguments. But is it legal and free of memory leaks and other...
5
2245
by: StephQ | last post by:
This is from a thread that I posted on another forum some days ago. I didn't get any response, so I'm proposing it in this ng in hope of better luck :) The standard explanation is that pointer...
6
9848
by: dtschoepe | last post by:
Hi all, Working on homework again... I've got a weird problem, I've been banging my head against the wall on what is causing it. I have a pointer to a typdef named Person. At one point in the...
5
4630
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
5
3613
by: Immortal Nephi | last post by:
I would like to design an object using class. How can this class contain 10 member functions. Put 10 member functions into member function pointer array. One member function uses switch to call...
7
3787
by: ghulands | last post by:
I am having trouble implementing some function pointer stuff in c++ An object can register itself for many events void addEventListener(CFObject *target, CFEventHandler callback, uint8_t...
0
7041
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6908
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...
1
6737
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
5336
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
4776
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
4481
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
2995
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1300
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
179
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.