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

functionpointer prototype with void* : question

P: n/a
hello,

no many words, I will start with an example instead

int foo(void *r) {...}

void test(void) {
int *x=0;
foo(x); /* seems to me as valid */
}
--------------------------------------------------------------
int foo(void(*cb)(void*r)) {...}
void bar(int *x) {...}

void test(void) {
foo(bar); /* seems to me as valid, but not for the compiler */
}

the question now is hopefully obvious. why can't I assign
a functionpointer where the only difference is void* vs.
int* in its arguments. the direct way is allowed, but the
indirect isn't. do I miss any important point (i think so).

thanks

best wishes

Andreas Klimas
Sep 15 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On Fri, 15 Sep 2006 01:12:52 GMT, Andreas Klimas
<kl****@klimas-consulting.comwrote:
>hello,

no many words, I will start with an example instead

int foo(void *r) {...}

void test(void) {
int *x=0;
foo(x); /* seems to me as valid */
This is valid because there is a defined implicit conversion from int*
(the type of x) to void* (the type the function needs/expects in r).
>}
--------------------------------------------------------------
int foo(void(*cb)(void*r)) {...}
void bar(int *x) {...}

void test(void) {
foo(bar); /* seems to me as valid, but not for the compiler */
This is not valid because there is no defined implicit conversion from
void(*)(int*) --the type of bar-- to void(*)(void*) -- the type the
function expects in cb, NOT r.
>}

the question now is hopefully obvious. why can't I assign
a functionpointer where the only difference is void* vs.
int* in its arguments. the direct way is allowed, but the
indirect isn't. do I miss any important point (i think so).
Consider when sizeof(void*) != sizeof(int*). In the first example,
the compiler knows a) foo is expecting a void*, b) x is an int*, and
c) how to convert one to the other. It can generate the code with no
problem.

In the second example, the compiler may not know anything at all about
how foo uses its argument (foo could be in a library). Let us assume
it uses the argument to call the function pointed to. The code in foo
will generate an argument of type void* and pass it to bar. bar, on
the other hand, is expecting an int*. It will attempt to extract an
int* from however the argument is passed. Since the two types have
different sizes, it will not extract the correct data.
>
thanks

best wishes

Andreas Klimas

Remove del for email
Sep 15 '06 #2

P: n/a
On Fri, 15 Sep 2006 01:12:52 GMT, Andreas Klimas
<kl****@klimas-consulting.comwrote in comp.lang.c:
hello,

no many words, I will start with an example instead

int foo(void *r) {...}
foo() is a function accepting a pointer to void and returning an int.
void test(void) {
int *x=0;
foo(x); /* seems to me as valid */
Due to the prototype for foo() being in scope, the compiler converts
'x' to pointer to void, an allowed automatic conversion, and calls
foo(). No problem.
}
--------------------------------------------------------------
int foo(void(*cb)(void*r)) {...}
This time, foo() is a function that returns an int and accepts a
pointer to a function. That function pointer must point to a function
that accepts a pointer to void and returns nothing.
void bar(int *x) {...}
bar() is a function that returns nothing, but accepts a pointer to
int. The function signature is different.
>
void test(void) {
foo(bar); /* seems to me as valid, but not for the compiler */
}

the question now is hopefully obvious. why can't I assign
a functionpointer where the only difference is void* vs.
int* in its arguments. the direct way is allowed, but the
indirect isn't. do I miss any important point (i think so).

thanks

best wishes

Andreas Klimas
The automatic conversion from "pointer to any object type" to "pointer
to void", and the reverse, is a direct top-level conversion only.

The language does not allow the automatic conversion of
void(*)(object_type*) to void(*)(void*).

The language does not allow the automatic conversion of object_type
**x to void **y.

These are not direct conversions of object_type* to void*.

You can use a cast to do what you want, but note that the actual
parameters passed to the function when it is called through the
pointer must match the function's definition, or the behavior is
undefined.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Sep 15 '06 #3

P: n/a

Andreas Klimas wrote:
int foo(void *r) {...}

void test(void) {
int *x=0;
foo(x); /* seems to me as valid */
}
--------------------------------------------------------------
int foo(void(*cb)(void*r)) {...}
void bar(int *x) {...}

void test(void) {
foo(bar); /* seems to me as valid, but not for the compiler */
}
Note that you may get away with:

int foo(void *) {...}
void bar(int *x) {...}

foo(bar)

The conversion from void * to function pointer
is not guaranteed to work on all platforms, and is certainly
not guaranteed by the language, but it does
work on many.

Sep 15 '06 #4

P: n/a
"Bill Pursell" <bi**********@gmail.comwrites:
Andreas Klimas wrote:
>int foo(void *r) {...}

void test(void) {
int *x=0;
foo(x); /* seems to me as valid */
}
--------------------------------------------------------------
int foo(void(*cb)(void*r)) {...}
void bar(int *x) {...}

void test(void) {
foo(bar); /* seems to me as valid, but not for the compiler */
}

Note that you may get away with:

int foo(void *) {...}
void bar(int *x) {...}

foo(bar)

The conversion from void * to function pointer
is not guaranteed to work on all platforms, and is certainly
not guaranteed by the language, but it does
work on many.
Passing a function pointer to a function expecting a void* is a
constraint violation; there's no implicit conversion from function
pointers to void*. An implementation can, as you say, accept it as an
extension -- but it must issue a diagnostic in conforming mode.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Sep 15 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.