Thread: How to create a generic Function Pointer?

  1. #1
    Registered User
    Join Date
    Nov 2016
    Location
    Hyderabad, India
    Posts
    6

    How to create a generic Function Pointer?

    The following is the code that I am currently struggling with:
    I want to have a function pointer whose return type can be of any data type and whose arguments can be of any data type (there can be multiple arguments).
    Code:
    #include<stdio.h>
    int* numbers(int *);
    char* alphabets(char[]);
    void* functions(void* (*myfunction)(void *));
    int main(int argc, char *argv[])
    {
        typedef void* (*myfunction)(void*);
        myfunction fun = &numbers;    
        char *array, letters[20] = {'v','i','v','e','n','\0'};
        int a = 2;
        int *y;
        y = fun(&a);
        printf("%d\n",*y);
        fun = &alphabets;
        array = fun(letters);
        printf("%s\n",array);
    }
    
    int* numbers(int *k)
    {
        return k;
    }
    
    char* alphabets(char *ptr)
    {
        return ptr;
    }
    
    void* functions(void* (*myfunction)(void *))
    {
        return myfunction;    
    }
    The above code is my attempt to achieve generic function pointer.

    Thank you.

  2. #2
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,687
    The C standard guarantees that any object pointer type can be converted to void* and back again without loss of information (meaning that the re-converted pointer will compare equal to the original one). There is no such guarantee for function pointers. An implementation could, for example, make void* 64 bits and function pointers 128 bits.

    But any function pointer can be converted to any other function pointer type and back again without loss of information.
    You can use, for example, void(*)(void) as a generic function pointer type:

    Code:
    typedef void (*funcptr)(void);
    You must convert back to the original pointer type before executing a call to avoid undefined behavior.
    Double Helix STL

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,114
    How do you suppose to stop yourself doing something dumb like
    fun = &numbers;
    array = fun(letters);

    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2016
    Location
    Hyderabad, India
    Posts
    6
    Quote Originally Posted by Salem View Post
    How do you suppose to stop yourself doing something dumb like
    fun = &numbers;
    array = fun(letters);

    Thanks for the reply.
    I think I was a little aware that I have used statments:
    Code:
    myfunction fun = &numbers;
    int a = 2;
    int *y;
    y = fun(&a); // fun, function pointer is pointing to int* numbers(int *); here
    Then

    Code:
    char* array, letters[20] = {'v','i','v','e','n','\0'};
    fun = &alphabets;
    array = fun(letters); // fun, the function pointer is now pointing to char* alphabets(char []); here.
    
    Error Message:
    arshadnazeer@mybox:~/nit/wander$ gcc fp.c
    fp.c: In function ‘main’:
    fp.c:8:19: warning: initialization from incompatible pointer type [enabled by default]
    myfunction fun = &numbers;
    ^
    fp.c:14:6: warning: assignment from incompatible pointer type [enabled by default]
    fun = &alphabets;

    Please may I know how I could have one function pointer point to two unique function with diverse return types and function arguments.
    Please explain my dumbness level.
    The following are the error messages that I see during compilation by gcc compiler, Linux Ubuntu.

    Thank you.
    Last edited by Arshad Nazeer; 01-08-2017 at 04:48 AM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,114
    The short answer is you can't, because there would be insufficient information within the function pointer type to allow the compiler to generate the right code to call the function in question.

    Like for example, if you had say
    void foo ( int a );
    void bar ( double b );


    What if (on some machine), int and double were passed in different registers. If the compiler cannot resolve at compile time what the function pointer is pointing to, then there is no way it can ever generate the correct calling sequence.

    Data has 'void*' as a kind of anonymous pointer, but you still have to cast it back to 'type*' in order to be able to access it properly.

    The nearest you're going to get is a printf-like function along the lines of
    void anyfunc( int type, ... );

    Which you could call with
    anyfunc( 0, 1 ); // 0 means single int
    anyfunc( 1, "hello" ); // 1 means single string
    anyfunc( 2, 1.345 ); // 2 means single float
    anyfunc( 3, "these", "are", "the", "parameters", NULL ); // 3 means NULL terminated list of strings
    // etc etc

    Then anyfunc has to look at the type parameter, then use va_args to correctly extract each following parameter according to it's type.
    printf does this my matching "%d" with integers, "%s" with strings etc.

    Now if you make "int type" a format string like printf's, then compilers like gcc can be instructed to do a parameter consistency check at compile time.


    You can have a single 'type' as a union, but it doesn't buy you much IMO. You still have to assign and call the right member of the union for it to work.
    Code:
    #include <stdio.h>
    
    int* numbers(int *);
    char* alphabets(char[]);
    void* functions(void* (*myfunction)(void *));
    
    typedef union {
      int * (*if_p)(int *);
      char* (*cf_p)(char *);
      void* (*vf_p)(void *);
    } pf_t;
    
    
    int main(int argc, char *argv[])
    {
        pf_t fun;
        fun.if_p = &numbers;    
        char *array, letters[20] = {'v','i','v','e','n','\0'};
        int a = 2;
        int *y;
        y = fun.if_p(&a);
        printf("%d\n",*y);
        fun.cf_p = &alphabets;
        array = fun.cf_p(letters);
        printf("%s\n",array);
    }
     
    int* numbers(int *k)
    {
        return k;
    }
     
    char* alphabets(char *ptr)
    {
        return ptr;
    }
     
    void* functions(void* (*myfunction)(void *))
    {
        return myfunction;    
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 11-23-2012, 11:49 PM
  2. generic pointer to char conversion problem
    By monkey_c_monkey in forum C++ Programming
    Replies: 5
    Last Post: 07-12-2012, 07:06 AM
  3. Generic pointer
    By neu_greg in forum C Programming
    Replies: 3
    Last Post: 04-02-2009, 02:30 PM
  4. Create generic classes to be specified later?
    By jmd15 in forum C++ Programming
    Replies: 18
    Last Post: 08-05-2007, 09:21 AM
  5. Generic Template Pointer
    By LuckY in forum C++ Programming
    Replies: 4
    Last Post: 10-20-2004, 01:13 PM

Tags for this Thread