Thread: simple pointer-to-func question.

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    47

    simple pointer-to-func question.

    Im doing a homework assignment and am stuck on a question which i feel should be rather easy, but is giving me a really hard time. Please help a guy out.

    how can you pass a "void pointer" to a pointer-to-function in order to make the pointer-to-function take more than one type of argument.


    Code:
    #include <iostream>
    using namespace std;
    
    void f1(int i)
    {
    	cout<< "result: " << i << endl;
    }
    
    void main()
    {
    void (*fp)(void*); //?? as apposed to=>    void (*fp)(int)
    fp = f1;
    fp(3);
    }
    Last edited by MegaManZZ; 08-02-2008 at 12:49 PM.

  2. #2
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Im no expert but:

    It seems to me if a functions parameter is a void * it is indeed taking any type of argument, but will of course require a cast at a later time to use.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I'm no expert either but if you are going to work with void pointers I think you'd need to change the signature of f1 and perform the necessary casts.

    Code:
    #include <iostream>
    using namespace std;
    
    void f1(void* i)
    {
    	cout<< "result: " << *static_cast<int*>(i) << endl;
    }
    
    int main()
    {
        void (*fp)(void*);
        fp = f1;
        int i = 3;
        fp(static_cast<void*>(&i));
    }
    (I'm not too sure about casting non-pointers to void*, since that is not allowed by static_cast.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    47
    I'm not sure if thats the solution he's looking for.. ill take it to account tho.. anyone have any other solutions.?

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you only ever have one function, then there's no point in making it void * -- one function can't, internally, handle two different types of arguments (except via the vararg and "format string" approach a la printf, or similar).

    If the idea is that you have func1, which really expects an int, and func2, which really expects a double, but you need compatible declarations so that the function pointers have the same type, then you're going to have to make both of them take a void *, and do some fancy casting when you call.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In C++, it's possible to convert any type into void* (so no cast is required). However, the other way around is not possible.
    But again, as tabstop notes, void* in C++ is not really a good idea, especially since it throws away type safety. Write functions that takes one type and works with it. When you later learn templates, you can write functions that works with a range of types w/o problems.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    In C++, it's possible to convert any type into void* (so no cast is required). However, the other way around is not possible.
    Any pointer type can be implicitly converted to a void * in both C and C++. Non-pointer types cannot.

    Quote Originally Posted by Elysia View Post
    But again, as tabstop notes, void* in C++ is not really a good idea, especially since it throws away type safety. Write functions that takes one type and works with it. When you later learn templates, you can write functions that works with a range of types w/o problems.
    Template functions are (literally) a template used by the compiler to generate a family of functions. They are not single functions that work on a range of types.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by grumpy View Post
    Any pointer type can be implicitly converted to a void * in both C and C++. Non-pointer types cannot.
    Yes, but &var would create T*, implicitly converted to void*. That was my point.

    Template functions are (literally) a template used by the compiler to generate a family of functions. They are not single functions that work on a range of types.
    If you want to be nit-picky, then sure, it is as you describe.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Templates would not work, because as grumpy says, they create a family of functions, each with there own type; you cannot create a pointer to the whole template, only an individual instance of it.

    What you can do is instead of using a function pointer, use a class that has an overloaded operator() with overloads for each acceptable argument set.

    The other thing that can be done is to take advantage of the fact that on most architectures, you can reinterpret_cast function pointers (but not method pointers) from one type to another. So like void pointer, you can designate a particular function type as a generic type and pass that around. When you need to use it, cast it to the right type and preform the call, much like you cast a void pointer before dereferencing.
    Last edited by King Mir; 08-03-2008 at 09:04 AM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I also wasn't thinking of using function pointers to the function, but calling it directly.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    I also wasn't thinking of using function pointers to the function, but calling it directly.
    ... which, unfortunately, wasn't the point (no pun intended) of the original question.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    And there's also this scenario (after some thinking):

    If the first function takes a static type, then we should know what the second function should take.
    And if the first function takes a dynamic type (say void*), then the second function will also have to take a dynamic type (void*).
    So in both cases, we know the type that it must take and can create a function prototype and a function pointer.

    So if we re-write the functions with template to takes the type T instead of void*, then the same rules apply and as the first function takes T, the second function takes T and we can safely create a function pointer anyway.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    I'm not getting what your saying.

    But the key difference between templates and the use of void pointer, is that templates provide static polimorphism, whereas void pointers provide dynamic polimorphism. If the variable field depends on runtime values, there is no way to use templates to solve the problem (except in conjunction with void pointers or class inheritance or va_args). On the other hand, if the type of the variable field can be determined compile time, then a template is the preferred tool.

    So while I do not understand your suggestion, I am extremely skeptical of the use of templates to solve a dynamic polimorphism problem as the op seems to imply.
    Last edited by King Mir; 08-04-2008 at 08:04 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Like this...
    Code:
    void foo2(int);
    
    void foo(int n)
    {
        typedef void (myptr)(int);
        myptr* myptr_ = &foo2;
        myptr_(n);
    }
    
    // Since foo has a static type as argument, we know what type foo2 must take.
    // No need for any templates here.
    void foo2(int) { }
    Example 2:
    Code:
    void foo2(void*);
    
    void foo(void* n)
    {
        typedef void (myptr)(void*);
        myptr* myptr_ = &foo2;
        myptr_(n); // What type is n???
    }
    
    // Since foo has a dynamic type, it's impossible for us to determine what type foo2 should 
    // take. Therefore, it will probably take the same type as foo, because foo cannot easily 
    // determine what type it has taken and what foo2 should take in that case.
    void foo2(void*) { }
    Therefore, a more viable solution are template functions:
    Code:
    template<typename T> void foo2(T);
    
    template<typename T> void foo(T n)
    {
        // We know now that foo2 must take an argument of T, so we get a specialized 
        // function pointer.
        typedef void (myptr)(T);
        myptr* myptr_ = &foo2<T>;
        // We now know the type of T. If we wanted to do some template-programming, we could 
        // easily created specialized functions and create appropriate function pointers.
        myptr_(n);
    }
    
    template<typename T> void foo2(T) { }
    Does this make sense?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    Does this make sense?
    No, it does not.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. a pointer to a function question..
    By transgalactic2 in forum C Programming
    Replies: 17
    Last Post: 10-21-2008, 11:47 AM
  2. Question about pointer arithmetic and types
    By brooksbp in forum C Programming
    Replies: 4
    Last Post: 08-22-2008, 01:53 PM
  3. Question About Pointer To Pointer
    By BlitzPackage in forum C++ Programming
    Replies: 2
    Last Post: 09-19-2005, 10:19 PM
  4. Pointer and segfaults question
    By kzar in forum C Programming
    Replies: 5
    Last Post: 09-15-2005, 09:03 AM
  5. pointer to pointer as argument question
    By Lateralus in forum C Programming
    Replies: 4
    Last Post: 07-21-2005, 05:03 PM