What is the use of function pointers? [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the point of function pointers?
I am trying to understand where in the practical scenarios function pointers are used.
and also can anyone please give me a practical example where we have to pass function itself as an argument to another function.

Function pointers can be useful when you want to create callback mechanism, and need to pass address of a function to another function.
They can also be useful when you want to store an array of functions, to call dynamically for example.

Callback routines appear to be the most common scenario put forth thus far. However, there are many others ...
Finite State Machines where the elements of (multi-dimensional) arrays indicate the routine that processes/handles the next state. This keeps the definition of the FSM in one place (the array).
Enabling features and disabling of features can be done using function pointers. You may have features that you wish to enable or disable that do similar yet distinct things. Instead of populating and cluttering your code with if-else constructs testing variables, you can code it so that it uses a function pointer, and then you can enable/disable features by changing/assigning the function pointer. If you add new variants, you don't have to track down all your if-else or switch cases (and risk missing one); instead you just update your function pointer to enable the new feature, or disable the old one.
Reducing code clutter I touched upon this in the previous example. Examples such as ...
switch (a) {
case 0:
func0();
break;
case 1:
func1();
break;
case 2:
func2();
break;
case 3:
func3();
break;
default:
funcX();
break;
}
Can be simplified to ...
/* This declaration may be off a little, but I am after the essence of the idea */
void (*funcArray)(void)[] = {func0, func1, func2, func3, funcX};
... appropriate bounds checking on 'a' ...
funcArray[a]();
There are many more. Hope this helps.

One common use is to implement a callback function.
Try to sort something by using qsort library function. It's last parameter is a pointer to the comparator function written by you.

The first thing that comes to my mind as a very useful application is a button. Take the following code:
int buttonID = CreateButton ("Click Me!", 100, 100, 200, 100, onClick);
This would create a button at (100,100) with width 200 and height 100. Every time you click it, onClick is called.
I use something similar in a personal Windows API wrapper. It makes creating buttons etc so much easier.

There are two major uses for function pointers:
callbacks - used for event handlers, parser specialization, comparator function passing...
plugins and extensions - the pointers to functions provided by plugins or library extensions are gatherd by a standard functio GetProcAddress, dlsym or similar, which take the function identifier as name and return a function pointer. Absolutely vital for APIs like OpenGL.

Well, the #1 stock answer is: qsort. The comparator routine that qsort will use is passed as a function pointer. A lot of other “generic algorithm” functions will take comparators in similar ways; e.g. perhaps a hashtable implementation might accept your hash function.
C-language GUI toolkits and application frameworks (e.g. Gnome/Gtk+/Glib) often accept function pointers as “callbacks” for timer or user interface events. (EG: “call this function whenever this button is clicked” or “…whenever this timer expires”)
In fact, most “OOP-like” or “event-driven” code in C will accept function pointers for a similar reason.

You can use it to pass a callback to a function. For instance, you might want to sort an array using qsort(). This function takes a comparison function as one of its arguments, which means that you can use your own sorting orders:
// All odd numbers are before even numbers
int cmpoddeven(const void *xp, const void *yp) {
int x = *((int*) xp);
int y = *((int*) yp);
if(x == y)
return 0;
if(x % 2 == y % 2) {
return (x < y ? -1 : 1);
if(x % 2 == 1)
return -1;
return 1;
}
int main() {
int array[] = {1, 2, 3, 4, 5};
// calling qsort with cmpoddeven as the comparison function
qsort(array, 5, sizeof(int), &cmpoddeven);
// array == {1, 3, 5, 2, 4};
}

In MOST cases, it's essentially the C way of doing dependency inversion. The wiki article states:
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
The classic example ofqsort does this in the sense that the higher-level sort function does not depend on the type, size, or comparison method of the data to be sorted. So if you qsort() an array of ints, the details are sizeof(int) and your compare implementation. The abstraction is an array of arbitrarily sized elements and a function that compares elements of that type.
See also: Inversion of Control.
I'm surprised no one has mentioned pthread_create() as an example.
The only common use I can think of that cannot be generalized as dependency inversion is implementing switch-like flow control on non-switchable data types. For example, if you've ever wanted to switch on a string, create arrays mapping sorted string keys to function pointers and do a binary search. It's not O(1) like a switch, but better than blindly doing strcmp()'s in a big if-else until you find a match. But maybe not any better than tokenizing the string and using an actual switch.

Related

Advantages of using callback (in a non-event driven program)

I am looking into an callback example in:
https://en.wikipedia.org/wiki/Callback_(computer_programming)
#include <stdio.h>
#include <stdlib.h>
/* The calling function takes a single callback as a parameter. */
void PrintTwoNumbers(int (*numberSource)(void)) {
int val1 = numberSource();
int val2 = numberSource();
printf("%d and %d\n", val1, val2);
}
/* A possible callback */
int overNineThousand(void) {
return (rand()%1000) + 9001;
}
/* Another possible callback. */
int meaningOfLife(void) {
return 42;
}
/* Here we call PrintTwoNumbers() with three different callbacks. */
int main(void) {
PrintTwoNumbers(&rand);
PrintTwoNumbers(&overNineThousand);
PrintTwoNumbers(&meaningOfLife);
return 0;
}
I understand all the functions. However, I am wondering except reducing a line, what's the advantage of doing:
PrintTwoNumbers(&overNineThousand);
rather than just using them like regular functions:
int a = overNineThousand();
PrintTwoNumbers(a);
Thanks!
This is a trivial example of what's known as a Higher Order Function.
In this particular example, it isn't very useful. You're right that it would be easier to just pass the data directly.
It's a technique that allows for the generalization of functions though, and is very helpful in reducing code duplication when used properly.
A typical example is the map function that transforms a list:
var arr = [1, 2, 3];
var newArr = arr.map(x => x + 1); // Pass a function that adds one to each element
print(newArr); // Prints [2, 3, 4]
Without higher order functions, you would have to write the same looping code that comprises map every time you want to transform a list. What if I wanted to add 2 to each element somewhere else? Or multiple each by 5? By passing a function, you can tell it how you want it to transform each item, without worrying about the iteration.
As noted in the comments, another example would be sorting functions. They allow you to pass a function that determines sort order. Without that ability, you would need to write a new sorting function for each different sort order and element type.
Sorry I couldn't answer this in C. I understand what's going on in the code you've posted, but I don't know C, so I couldn't give good example code that uses HOFs.
If the question is just computing one element, then yes, a callback is not very useful.
Now if we consider that the function may need to call the callback several times in a (non-)deterministic way, then a callback is required.
Typically, one of the most common callback in C is qsort where the callback is mandatory.
There are at least two situations in which callbacks are useful:
Functions in which a task is performed repeatedly on some data. The example given in the comments is good: a comparison function passed into a sort function as a callback is a good example of a useful callback.
Enumeration functions. This is when you ask a library for a list of objects and you want to act on each one. You would pass a callback to the enumeration function. Example: EnumWindows.

When to return value from function, and when to use out parameter? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm learning C and programming in general, and I don't know when to return a value and when to use void.
Is there any rule to apply when to use one over the another ?
Is there any difference between this two cases? I know that first case is
working with a local copy of int (n) , and second with original value.
#include <stdio.h>
int case_one(int n)
{
return n + 2;
}
void case_two(int *n)
{
*n = *n + 2;
}
int main(int argc, char *argv[])
{
int n = 5;
n = case_one(n);
printf("%i\n", n);
n = 5;
case_two(&n);
printf("%i\n", n);
return 0;
}
There is one more reason to use out param instead of return value - error handling. Usually return value (int) of the function call in C represents success of the operation. Error represented by not 0 value.
Example:
#include <stdio.h>
int extract_ip(const char *str, int out[4]) {
return -1;
}
int main() {
int out[4];
int rv = extract_ip("test", out);
if (rv != 0) {
printf("Error :%d", rv);
};
}
This approach used in POSIX socket API for example.
It very much depends on what you want to do, but basically You should use the former unless You have a good reason to use the latter.
Think of the implications of the choices. First, let's think about the way we provide input to function. It is quite often that you provide explicitly constant, compile-time constant or temporary data as input:
foo(1);
const int a = 2;
foo(a);
int x = 5;
int y = 5;
foo(x + y);
In all of the above cases the source of initial value is not a viable location for storing the result.
Next, let's think about how we may want to store the result. Foremost we may often want to use the result elsewhere. It may be inconvenient to use the same variable to store and then pass input, and to store output. But furthermore, often we would like to use the result immediately. We invoke the function as a part of larger expression:
x = foo(1) + foo(2);
Rewriting the preceding line in a manner that would use a pointer would require much unnecessary code - that is time and complication that we certainly don't want, when it's not really buying anything.
So when do we actually want to use a pointer? C functions are pass-by-value. Whenever we pass anything, a copy is created. We can then work on that copy and upon returning it, it requires copying again. If we do know that all we want to do is manipulate certain data set in place, we can provide a pointer as a handler and all that is copied is several bytes that store address.
So the former, prevalent way to create functions is flexible and leads to concise usage. The latter is useful for manipulation of objects in place.
Obviously sometimes our input actually is an address, and that's a trivial case for using pointers as function parameters.
I'm learning C and programming in general, and i don't know when to return a value and when to use void.
There is no definitive rule, and it is a matter of opinion. Notice that you might re-code your case_one as the following:
// we take the convention that the first argument would be ...
// a pointer to the "result"
void case_one_proc(int *pres, int n) {
*pres = n+2;
}
then a code like
int i = j+3; /// could be any arbitrary expression initializing i
int r = case_one(i);
is equivalent to
int i = j+3; // the same expression initializing i
int r;
case_one_proc(&r, i); //we pass the address of the "result" as first argument
Hence, you can guess that you might replace any whole C program with an equivalent program having only void returning functions (that is, only procedures). Of course, you may have to introduce supplementary variables like r above.
So you see that you might even avoid any value returning function. However, that would not be convenient (for human developers to code and to read other code) and might not be efficient.
(actually you could even make a complex C program which transforms the text of any C program -given by their several translation units- into another equivalent C program without any value returning function)
Notice that at the most elementary machine code level (at least on real processors like x86 and ARM), everything are instructions, and expressions don't exist anymore! And you favorite C compiler is transforming your program (and every C program in practice) into such machine code.
If you want more theory about such whole-program transformations, read about A-normal forms and about continuations (and CPS transformations)
Is there any rule to apply when to use one over the another ?
The rule is to be pragmatic, and favor first the readability and understandability of your source code. As a rule of thumb, any pure function implementing a mathematical function (like your case_one, which mathematically is a translation) is better coded as returning some result. Conversely, any program function which has mostly side effects is often coded as returning void. For cases in between, use your common sense, and look at existing practice -their source code- in existing free software projects (e.g. on github). Often a side effecting procedure might return some error code (or some success flag). Read documentation of printf & scanf for good examples.
Notice also that many ABIs and calling conventions are passing the result (and some arguments) in processor registers (and that is faster than passing thru memory).
Notice also that C has only call by value.
Some programming languages have only functions returning one value (sometimes ignored, or uninteresting), and have just expressions, without any notion of statement or instruction. Read about functional programming. An excellent example of a programming language with only value returning functions is Scheme, and SICP is an excellent introductory book (freely available) to programming that I strongly recommend.
The first approach is preferred, where you return a value. The second can be used when multiple values are computed by the function.
For example, the function strtol has this prototype:
long strtol(const char *s, char **endp, int base);
strtol attempts to interpret the initial portion of the string pointed to by s as the representation of a long integer expressed in base base. It returns the converted value with a return statement, and stores a pointer to the character that follows the number in s into *endp. Note however that this standard function should have returned 3 values: the converted value, the updated pointer and a success indicator.
There are other ways to return multiple values:
returning a structure.
updating a structure to which you receive a pointer.
C offers some flexibility. Sometimes different methods are equivalent and choosing one is mostly a matter of conventions, personal style or local practice, but for the example you give, the first option is definitely preferred.

Technically, can all functions be a void function?

For example:
int f1() {
return 3;
}
void f2(int *num) {
*num = 3;
}
int n1, n2;
n1 = f1();
f2(&n2);
With f1, we can return a value and do "variable=f1()"
But the same can be done with a void function that updates the value of that variable given its address without having to do "variable=f1()".
So, does this mean that we can actually just use void functions for everything? Or is there something that a void function cannot do to replace another int function/(type) function?
The main problem with making everything a void function (which in some people's lexicon is called a "routine") is that you can't chain them easily:
f(g(x))
becomes, if you really want to chain it:
int gout;
f((g(x, &gout), gout))
Which is painful.
Yes you could use void return types for everything and rely exclusively on returning via modified parameters. In fact, you could avoid using functions entirely and put everything in your main method.
As with any other feature of the language, return values give you particular advantages, and its up to you to decide if you want them. Here are some advantages of return values off the top of my head:
Returned values can be assigned to const variables, which can make your code easier to reason about
Certain types of optimisation can be applied by the compiler for returned values (this is more applicable to C++ RVO but may also apply to C's structs; I'm not sure)
Code which uses returned values is often easier to read, especially when the functions are mathematical (e.g. imagine having to declare all the temporaries manually for a large mathematical operation using sin/cos/etc. if they required the output to be via parameters). Compare:
double x = A*sin(a) + B*cos(b);
with
double tmpA, tmpB;
sin(&tmpA, a);
cos(&tmpB, b);
double x = A * tmpA + B * tmpB;
or to use a similar structure as John Zwinck suggested in his answer:
double tmpA, tmpB;
double x = A * (sin(&tmpA, a), tmpA) + B * (cos(&tmpB, b), tmpB);
It is guaranteed that the value will be set no matter what happens inside the function, as this is enforced by the compiler (except some very special cases such as longjumps)
You do not need to worry about checking if the assigned value is used or not; you can return the value and if the requester doesn't need it, they can ignore it (compare this to needing NULL-checks everywhere in your alternative method)
Of course there are also disadvantages:
You only get a single return value, so if your function logically returns multiple types of data (and they can't logically be combined into a single struct), returning via parameters may be better
Large objects may introduce performance penalties due to the need to copy them (which is why RVO was introduced in C++, which makes this much less of an issue)
So, does this mean that we can actually just use void functions for everything?
Indeed. And as it turn out, doing so is a fairly common coding style. But rather than void, such styles usually state that the return value should always be reserved for error codes.
In practice, you usually won't be able to stick to such a style consistently. There are a some special cases where not using the return value becomes inconvenient.
For example when writing callback functions of the kind used by standard C generic functions bsearch or qsort. The expect a callback of the format
int compare (const void *p1, const void *p2);
where the function returns less than zero, more than zero or zero. Design-wise it is important to keep the parameters passed as read-only, you wouldn't want your generic search algorithm to suddenly start modifying the searched contents. So while there is no reason in theory why these kind of functions couldn't be of void return type too, in practice it would make the code uglier and harder to read.
Of course you could; but that does not make it a good idea.
It may not always be convenient or lead to easy to comprehended code. A function returning void cannot be used directly as an operand in an expression. For example while you could write:
if( f1() == 3 )
{
...
}
for f2() you would have to write:
f2( &answer ) ;
if( answer )
{
...
}
Another issue is one of access control - by passing a pointer to the function you are giving that function indirect access to the caller's data, which is fine so long as the function is well behaved and does not overrun. A pointer may refer to a single object or an array of objects - the function taking that pointer has to impose appropriate rules, so it is intrinsically less safe.

Calling function with variable arguments dynamically

Is there a possibility to call function with variable arguments from the C code dynamically?
For example I have text file which contains data (written using this scheme: function_name arguments) for example:
func1 1 2 3
func2 1
func3
My program written in C is parsing this file and looks in a populated array (which holds function name in string and target native function pointer) for function with given name by comparing the string and calls a pointer of this function with arguments from the text file. For example functions like that:
void func1(int a, int b, int c) { }
void func2(int a, int b) { }
void func3() { }
The problem is that even if I know the number of arguments, I don't know how to write in C function pointer call with dynamic number of arguments. Is there a possibility to populate va_list (I know that this is NOT a container or a typical array!) then pass to the native function or any other way to do this? The only way which came into my mind is populating dynarec block with x86 code for calling native function with variable arguments, but it's not a clean solution. Is such thing even possible in plain C?
If it is hard to understand just write and I'll try to explain better. And if you want to write "use va_list" - then read carefully my post once again.
Thanks in advance.
I'm self answering, because this will be a solution for other people. If you want to call functions with variable arguments dynamically without writing direct machine code just use avcall library from FFCALL. Quick reference guide of avcall library can be found here. It's a crossplatform library that makes this possible. For example to call function named func1 with return type void which takes three arguments and all of them are of type int just do this:
#include <avcall.h>
int a = 1, b = 2, c = 3;
av_alist alist;
av_start_void(alist,&func1);
av_int(alist,a);
av_int(alist,b);
av_int(alist,c);
av_call(alist);
You can of course use this for functions which returns value or takes arguments of different type, for more just look at avcall library manual page. :)
I like your way of thinking, because obviously, you are a true hacker, but...
do not try to do it like this.
The proper way of doing this is to go alter these functions so that each one of them accepts an array of int instead of individual int parameters. But I suppose that if you had the freedom to change them, you would have done it already and you would not be asking.
The next best way of doing it is to write a number of functions, conv1(), conv2(), conv3() etc, each accepting an array of int, and a pointer to a function which accepts individual int parameters. So, convN() accepts an array of N integers, and a pointer to a function which accepts N individual int parameters. It reads each int from the array and passes it to the function as a parameter. It can do this, because it has been specifically written to work with a function of precisely that number of parameters. Then, in your table with function names and pointers to functions, add a pointer to the right convN() function, depending on the number of parameters that the target function expects.
Don't hack it.

Why use a callback instead of a normal function call?

I'm trying to understand callbacks, and do get the idea, but do not understand why it is really needed.
Specifically, what added benefit does it provide over a normal function call? I'm looking at the accepted answer here : What is a "callback" in C and how are they implemented?
I have redone the same thing below, just without using function pointers. How is that different from this?
void populate_array(int *array, size_t arraySize)
{
for (size_t i=0; i<arraySize; i++)
array[i] = getNextRandomValue();
}
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10);
...
}
Is it only beneficial if lower-layer software needs to call a function that was defined at a higher-layer?
This implementation is different in that the only way it knows to populate the array is hard-coded: getNextRandomValue is the way it populates the array, and it is part of the library that provides the populate_array functionality. Essentially, the two functions are baked together into a single whole (the fancy way of saying the same thing is to say that they are "tightly coupled").
With the original implementation I can do all of the things below without changing a line in the populate_array:
int getNextRandomValue(void) {
return rand();
}
int getNextEvenValue(void) {
static int even = 2;
return (even += 2);
}
int getNextNegativeValue(void) {
static int neg = -1;
return neg--;
}
int getNextValueFromUser(void) {
int val;
scanf("%d", &val);
return val;
}
populate_array(myarray, 10, getNextRandomValue);
populate_array(myarray, 10, getNextEvenValue);
populate_array(myarray, 10, getNextNegativeValue);
populate_array(myarray, 10, getNextValueFromUser);
With your implementation I would have to write a separate populate_array for each of these cases. If the way of populating an array that I need is not part of the library, I am on the hook for implementing the whole populate_array, not only its value-producing generator function. This may not be that bad in this case, but in cases where callbacks really shine (threads, asynchronous communications) reimplementing the original without callbacks would be prohibitive.
In your example, getNextRandomValue must be known at compile time. This means that you cannot reuse the function with different definitions of getNextRandomValue, neither let other users link to your code and specify their version of getNextRandomValue. Note that this is not a callback, rather a "generic" function: think of getNextRandomValue as a placeholder for a function.
Callbacks are a special use of "generic" functions: they are called upon completion of an asynchronous task, to notify the user of the operation results (or progress).
I don't think that function pointers only suit low-to-high-level communication. Function pointers, as said, allow you to build generic code in C. A quick example, qsort(): order sorting needs a function that, given a and b, tells whether a>b, a<b or a==b, so that a and b can be placed in the right order. Well, qsort let you provide your own definition for order, thus offering a general, reusable piece of code.
To refine other answers here: Your function populate_array has a bad name. It should be named populate_array_with_random_values.
As said in the answer you linked to "there is no callback in c". There only is a method to pass pointers to function to a function.
Which is useful in general not only for lower-layer software that needs to call a function on a higher-level though this might be often how it is used.
Passing function pointers as parameters is an elegant way to write code. In your example if you want to have two variations on how to get the next random value you already see how it is much easier to pass the function as a parameter rather then trying to pass a parameter that then selects the next function to call using a switch.

Resources