470,849 Members | 1,129 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,849 developers. It's quick & easy.

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 1250
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 discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by msolem | last post: by
14 posts views Thread by Bryan Parkoff | last post: by
6 posts views Thread by dtschoepe | last post: by
5 posts views Thread by Tim Frink | last post: by
5 posts views Thread by Immortal Nephi | last post: by
7 posts views Thread by ghulands | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.