#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2

    Function pointer


    Can anyone explain why do we need function pointers ? Where it is used ?
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Jump tables.

    Passing to a function the function that it will need to call, selectable at run-time.

    Passing to a CreateThread call the function that the thread will execute.

    Just off the top of my head.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    The standard library function qsort uses function pointers
    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
  6. #4
  7. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,109
    Rep Power
    1802
    It is the address of a function through which the function can be called. Since it is a variable, the call can be dynamically determined at runtime rather than fixed when the code is built.

    One use is in callbacks where you can for example pass a pointer to a function to some library code so that that library can call your code without prior knowledge of its existence. This is how the standard library qsort() function works for example to allow it to sort any type of object using user defined ordering rules.

    There was once an excellent web site www.function-pointers.org which provided more that you would ever need to know about the subject, but it appears to be down or extinct. A reasonable summary of the subject can be found here

    Comments on this post

    • shilpac agrees
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    13
    Rep Power
    0
    Originally Posted by shilpac
    Can anyone explain why do we need function pointers ? Where it is used ?
    Function pointers add C++ like properties to C. You can create class like behaviour using structs and function pointers... Function pointers allows you to use functions like a variable and since functions have power to do something organization of complex programs can be more easier and flexible. You can create more generic behaviours and abstraction can be achieved. void pointers are also used frequently with function pointers.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2
    Thanks guys.
  12. #7
  13. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,109
    Rep Power
    1802
    Originally Posted by serafon
    Function pointers add C++ like properties to C.
    That is a bit misleading - C has always supported function pointers, long before C++ even existed - nothing has been "added". In fact it is the other way around, C++ uses function pointers to enable some of its features such as virtual functions. But if that is what you are trying to achieve - just use C++!
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    8
    Rep Power
    0
    A function pointer can be used to make your code more "flexible" and ultimately easier to use.

    Suppose you want a function called get_data which prompts the user for some number, and then validates that number based on some rule which is context-dependent. In this case, we can define some simple validator functions and then give the name of the function to our get_data function.

    C Code:
    #include <stdio.h>
    #include <stdbool.h>
     
    // get_data(data, prompt, validator): Read data from user and use a custom validator.
    // The data is verified by calling the specified validator. If the validator returns false,
    // then the prompt is repeated until the user enters valid data.
    void get_data(double *data, const char *prompt, bool (*validator)(double));
     
    // Validator functions: these should return true if the value is valid; false otherwise.
    bool validate_height(double height);
    bool validate_weight(double weight);
    bool validate_any(double any) {return true;}  // always valid
     
    // main: demonstrate use of get_data() with function pointers
    int main()
    {
    	double height, weight, random;
    	get_data(&height, "Enter your height in cm: ", validate_height);
    	get_data(&weight, "Enter your weight in kg: ", validate_weight);
    	get_data(&random, "Enter a random number: ", validate_any);
     
    	printf("\nThanks, here is your info summary:\n"
    			"Height: %.2f cm\n"
    			"Weight: %.2f kg\n"
    			"Random: %g\n", 
    			height, weight, random);
    	return 0;
    }
     
    bool validate_height(double height)
    {
    	if (height < 5.0 || height > 300.0)
    		return false;
    	return true;
    }
     
    bool validate_weight(double weight)
    {
    	if (weight < 10.0 || weight > 500.0)
    		return false;
    	return true;
    }
     
    void get_data(double *data, const char *prompt, bool (*validator)(double))
    {
    	for (;;) {
    		printf("%s", prompt);
    		if (scanf("%lf", data) != 1) {
    			fflush(stdin);  // skip over non-numeric data
    			printf("A number is required.\n");
    			continue;
    		}
    		getchar();  // skip whitespace
    		if ((*validator)(*data))
    			return;
    		printf("Sorry, that was not a valid number.\n");
    	}
    }


    Using such a scheme is nice, because if we add more rules later, we don't need to change get_data to handle them. We just define another function and pass it along. The get_data function does "the right thing" as long as the validator is properly defined.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    3
    What if the function takes arguments? Then is it still possible to select the function by dereferencing a pointer to the function that changes at run time? I think not.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    13
    Rep Power
    0
    Originally Posted by EEmaestro
    What if the function takes arguments? Then is it still possible to select the function by dereferencing a pointer to the function that changes at run time? I think not.
    Function already has parameters if you look carefully. There is no difference from an ordinary function, it has all the capabilities.

    One problem here is, (actually not a problem but getting more flexibility) using functions with different number of arguments. Because there is no restriction about arguments of the function that the pointer points to but the number and type should be always same.

    One solution is to use va_arg, va_list etc (i also asked in another topic) and second may be an argument which is a void pointer and points to a structure of arguments.
  20. #11
  21. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,109
    Rep Power
    1802
    Originally Posted by EEmaestro
    What if the function takes arguments? Then is it still possible to select the function by dereferencing a pointer to the function that changes at run time? I think not.
    That can be done without any problem; did you look at any of the links already posted? The function passed to qsort() for example takes two arguments.

    For example:

    Code:
    double(*trig_fn)(double);
    trig_fn = &sin ;
    double x = trig_fn( theta ) ;
    Note that explicit de-referencing is not required, though allowed.

    In the function pointer declaration, the return value and the parameter types form part of the function-pointer type. At compile time at least, the data type is checked for consistency. You can also have a generic function pointer type and cast it to another in order to force a call for which the parameter types are not a match - obviously you'd do that with care, but it is sometimes useful - for example you might have a call back that does not need any parameters being called from a library that provides parameters. In this case you could have a dummy parameter and ignore it or cast the pointer to the accepted type.

    In C the stack frame setup-up and tear down code is performed by the caller not the called function, so nothing bad happens in terms of stack management, but interpreting arguments that were not explicitly passed will only yield junk, modifying such parameters or dereferencing pointer arguments will likely cause memory corruption and even more trouble.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    8
    Rep Power
    0
    Originally Posted by clifford
    Note that explicit de-referencing is not required, though allowed.
    Indeed. The above example can also be written (more clearly in my opinion):

    C Code:
    	double (*trig_fn)(double);
    	trig_fn = sin ;
    	double x = (*trig_fn)(theta);


    This is the style used by the K&R book to explain function pointers. The unadorned sin should already be an address, and the identifier (*trig_fn)(...) has the type `double', wheras the unadorned trig_fn has type `double (*)(double)'
  24. #13
  25. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    13
    Rep Power
    0
    Originally Posted by clifford
    In C the stack frame setup-up and tear down code is performed by the caller not the called function, so nothing bad happens in terms of stack management, but interpreting arguments that were not explicitly passed will only yield junk, modifying such parameters or dereferencing pointer arguments will likely cause memory corruption and even more trouble.
    Can you explain this more please? Do you say it is not a good idea to pass in a void pointer to a function that points to a parameter list and dereference it in the called function?

IMN logo majestic logo threadwatch logo seochat tools logo