easy pointers to functions problem

Discussion in 'C Programming' started by Michael, Jul 27, 2006.

  1. Michael

    Michael Guest

    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
    Michael, Jul 27, 2006
    #1
    1. Advertising

  2. Michael

    Flash Gordon Guest

    Michael wrote:
    > 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!
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
    Flash Gordon, Jul 27, 2006
    #2
    1. Advertising

  3. Michael wrote:
    > #include <stdio.h>
    >
    > void do_stuff(int*,int,void*);


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

    <snip>

    > void do_stuff(int *a, int size, void (*process)(int *)){
    > int i;


    <snip>
    lovecreatesbeauty, Jul 27, 2006
    #3
  4. Flash Gordon wrote:
    > Michael wrote:
    > > printf("error");

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


    Do you point to a '\n'.
    lovecreatesbeauty, Jul 27, 2006
    #4
  5. Michael

    Flash Gordon Guest

    lovecreatesbeauty wrote:
    > Flash Gordon wrote:
    >> Michael wrote:
    >>> printf("error");

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

    >
    > Do you point to a '\n'.


    Indeed. Thank's for the correction.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
    Flash Gordon, Jul 27, 2006
    #5
  6. Michael

    Michael Guest

    "Flash Gordon" <> wrote in message
    news:-gordon.me.uk...
    > Michael wrote:
    >> 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.


    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.

    >> }
    >> }
    >>
    >> 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!
    > --
    > Flash Gordon, living in interesting times.
    > Web site - http://home.flash-gordon.me.uk/
    > comp.lang.c posting guidelines and intro:
    > http://clc-wiki.net/wiki/Intro_to_clc
    Michael, Jul 27, 2006
    #6
  7. Michael

    Flash Gordon Guest

    Michael wrote:
    > "Flash Gordon" <> wrote in message
    > news:-gordon.me.uk...
    >> Michael wrote:
    >>> 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.

    >
    > 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.

    <snip>

    > 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.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
    Flash Gordon, Jul 27, 2006
    #7
  8. Michael

    Default User Guest

    Michael wrote:

    > 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
    Default User, Jul 27, 2006
    #8
  9. Default User wrote:
    > This is one of those cases where typedefs can be useful:
    >
    > <http://c-faq.com/decl/pfitypedef.html>


    I think typedef is unuseful totally.
    lovecreatesbeauty, Jul 28, 2006
    #9
  10. In article <>, "lovecreatesbeauty" <> writes:
    >
    > Default User wrote:
    > > This is one of those cases where typedefs can be useful:
    > >
    > > <http://c-faq.com/decl/pfitypedef.html>

    >
    > 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.

    --
    Michael Wojcik

    I am a realistic background detail. -- Bruce Schneier (on his mention in
    _The Da Vinci Code_)
    Michael Wojcik, Jul 28, 2006
    #10
  11. On Thu, 27 Jul 2006 06:13:14 UTC, "Michael" <>
    wrote:

    > 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!
    Herbert Rosenau, Jul 28, 2006
    #11
  12. On 28 Jul 2006 16:42:43 GMT, (Michael Wojcik)
    wrote:

    >
    > In article <>, "lovecreatesbeauty" <> writes:


    > > 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. <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
    Dave Thompson, Aug 7, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. S?ren Gammelmark
    Replies:
    1
    Views:
    1,871
    Eric Sosman
    Jan 7, 2005
  2. Marc Thrun
    Replies:
    15
    Views:
    850
    Tim Rentsch
    Oct 4, 2005
  3. newbie

    Pointers to char pointers in functions

    newbie, Sep 18, 2006, in forum: C Programming
    Replies:
    9
    Views:
    300
    August Karlstrom
    Sep 24, 2006
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    657
  5. ajaybgr
    Replies:
    18
    Views:
    953
    Philip Lantz
    Sep 7, 2012
Loading...

Share This Page