easy pointers to functions problem

M

Michael

Hi,

I am trying to get an idea of how function pointers work.
I have the following:

#include <stdio.h>

void do_stuff(int*,int,void*);
void getInt(int*);
void showInt(int*);

int main(){

int num_array[10];

do_stuff(num_array, 10, getInt);
do_stuff(num_array, 10, showInt);

return(0);
}

void do_stuff(int *a, int size, void (*process)(int *)){
int i;
for(i = 0; i < size; i++){
process(&a);
}
}

void getInt(int *ptr){
if((scanf("%d", ptr)) != 1){
printf("error");

}
}

void showInt(int *ptr){
printf("%d", *ptr);
}

but I get errors "conficting types for do_stuff" and also warnings "ISO C
forbids passing of arg3 of do_stuff between pointer and void *"

I'm getting nowhere fast here. Can someone help me out with what I have
wrong?

Thanks

Michael
 
F

Flash Gordon

Michael said:
Hi,

I am trying to get an idea of how function pointers work.
I have the following:

#include <stdio.h>

void do_stuff(int*,int,void*);

Here the last parameter of do_stuff is void*. void* is *not* compatible
with function pointers, only object pointers (i.e. pointers to data).
I.e. you cannot pass a function pointer as a void* parameter.
void getInt(int*);
void showInt(int*);

int main(){

If you are not using the parameters, it is better to be explicit.

int main(void) {
int num_array[10];

do_stuff(num_array, 10, getInt);
do_stuff(num_array, 10, showInt);

Why the magic number 10? I would use a #define for the array size, then
there is only one place to change it.
return(0);
}

void do_stuff(int *a, int size, void (*process)(int *)){

This is different to your prototype of do_stuff above, just as the
compiler told you! It is this that is correct, so change your earlier
prototype to match.
int i;
for(i = 0; i < size; i++){
process(&a);
}
}

void getInt(int *ptr){
if((scanf("%d", ptr)) != 1){
printf("error");


You might want a /n at the end of that printf. Or use puts.
}
}

void showInt(int *ptr){
printf("%d", *ptr);
}

but I get errors "conficting types for do_stuff"

The above error is obvious. Your prototype and definition don't match.
It's a bit like you telling someone you will give them an orange and
then giving them a cricket bat, of course they will tell you that they
are different!
> and also warnings "ISO C
forbids passing of arg3 of do_stuff between pointer and void *"

This is less obvious. void* is only a generic pointer to object (i.e.
data), it cannot point to functions. Imagine a system with 32bit data
pointers and 64bit function pointers. 64 does not do in to 32!
 
M

Michael

Flash Gordon said:
Here the last parameter of do_stuff is void*. void* is *not* compatible
with function pointers, only object pointers (i.e. pointers to data). I.e.
you cannot pass a function pointer as a void* parameter.

I thought this was where my problem was, but when I tried to declare it many
other ways
I always ended up with a syntax error.

Could you tell me how I should declare it please? In the book I am working
from none of the
function prototypes are declared, they are all just declared implicitly.....
void getInt(int*);
void showInt(int*);

int main(){

If you are not using the parameters, it is better to be explicit.

int main(void) {
int num_array[10];

do_stuff(num_array, 10, getInt);
do_stuff(num_array, 10, showInt);

Why the magic number 10? I would use a #define for the array size, then
there is only one place to change it.

I was aware that I had a 'magic' number here, but as I was only writing this
to try and figure out
where everything else was wrong, I didn't bother with the #define. My
appologies.
return(0);
}

void do_stuff(int *a, int size, void (*process)(int *)){

This is different to your prototype of do_stuff above, just as the
compiler told you! It is this that is correct, so change your earlier
prototype to match.
int i;
for(i = 0; i < size; i++){
process(&a);
}
}

void getInt(int *ptr){
if((scanf("%d", ptr)) != 1){
printf("error");


You might want a /n at the end of that printf. Or use puts.


again, I don't really care about the output, I just want to get the function
pointer stuff working, but fair comment.

Thanks for the help, I really apppreciate it.
 
F

Flash Gordon

Michael said:
I thought this was where my problem was, but when I tried to declare it many
other ways
I always ended up with a syntax error.

Could you tell me how I should declare it please? In the book I am working
from none of the
function prototypes are declared, they are all just declared implicitly.....

Further down you defined the function as
void do_stuff(int *a, int size, void (*process)(int *)){
/* stuff */
}

Therefore, a prototype for it would be
void do_stuff(int *a, int size, void (*process)(int *));
I.e. the only difference is it ends with a semi-colon instead of being
followed by the body of the function.

It is good that you have decided to not rely on implicit declarations,
since they do not always work properly.

again, I don't really care about the output, I just want to get the function
pointer stuff working, but fair comment.

Thanks for the help, I really apppreciate it.

No problem. I point out more than your current problem (as do others)
because this gives you more opportunity to learn.
 
D

Default User

Michael said:
Hi,

I am trying to get an idea of how function pointers work.
I have the following:
but I get errors "conficting types for do_stuff" and also warnings
"ISO C forbids passing of arg3 of do_stuff between pointer and void *"

I'm getting nowhere fast here. Can someone help me out with what I
have wrong?

This is one of those cases where typedefs can be useful:

<http://c-faq.com/decl/pfitypedef.html>




Brian
 
M

Michael Wojcik

I think typedef is unuseful totally.

There is at least situation where it is the only solution: for
using certain types with the va_arg macro. va_arg requires that
if used with type T, as in va_arg(ap, T), that T* be a pointer
to an object of type T.

This doesn't work with function pointers. Given a function
pointer of type "T (*)(P)", a pointer-to-function-pointer for that
type is "T (**)(P)". "T (*)(P)*" is syntactically invalid.

So if you have a variadic function that takes arguments with
function-pointer types, you MUST use typedef in order to retrieve
those arguments. typedef works because if you create a typedef
TD for a function pointer type, then TD* is a pointer-to-function-
pointer.

Now you could wrap those function pointers in structs and pass
them that way, but that's inconvenient for the caller, and may not
be the interface you want.
 
H

Herbert Rosenau

Hi,

I am trying to get an idea of how function pointers work.
I have the following:

#include <stdio.h>

void do_stuff(int*,int,void*);

No, you means

void do_stuff(int *a, int size, void (*process)(int *));

as the 3th parameter is truly not a pointer to void but to a function
returning voind and getting a single parameter of type pointer to
void. You have to declare the prototype always like a function
definition - but without the definition itself.

void getInt(int*);

Better selfdocumenting:
void getInt(int *ptr);
void showInt(int*);

and
void showInt(int *ptr);

Ther compiler will still ignore the name of the parameter in a
prototype but the reader will assign some description with it when the
name of the parameter does describe it.
int main(){

int num_array[10];

do_stuff(num_array, 10, getInt);
do_stuff(num_array, 10, showInt);

return(0);
}

void do_stuff(int *a, int size, void (*process)(int *)){
int i;
for(i = 0; i < size; i++){
process(&a);
}
}

void getInt(int *ptr){
if((scanf("%d", ptr)) != 1){
printf("error");

}
}

void showInt(int *ptr){
printf("%d", *ptr);
}

but I get errors "conficting types for do_stuff" and also warnings "ISO C
forbids passing of arg3 of do_stuff between pointer and void *"

I'm getting nowhere fast here. Can someone help me out with what I have
wrong?

Thanks

Michael



--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
D

Dave Thompson

There is at least situation where it is the only solution: for
using certain types with the va_arg macro. va_arg requires that
if used with type T, as in va_arg(ap, T), that T* be a pointer
to an object of type T.

This doesn't work with function pointers. <snip>

Also "true" array pointers, that is with actual type pointer to array
instead of the normal convention of pointer to (first) element.
Although it is arguable these are less common -- and certainly less
vital -- than function pointers.

The syntax also doesn't work for function types and array types --
int (double) * and int [5] * are syntactically invalid -- but as those
types can never be arguments (var or not) anyway, the inability to
fetch them with va_arg becomes of distinctly lesser importance.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top