Lundu Harianja
Lundu Harianja

Reputation: 463

callback function vs ordinary function in C

I'm learning about callback function in C and find myself too hard to understand the concept of callback.

As i know callback function is implemented using function pointer in c,means that we can refer to a function through the use of pointer just like we used pointer to refer to a variable.

I have two implementation of function here:

1.The first is using callback function

#include <stdio.h>

int add_two_number(int a, int b);
int call_func(int (*ptr_func)(int, int), int a, int b);

int main (int *argc, char *argv[])
{
     printf("%d", call_func(add_two_number, 5, 9));

     return 0;
}

int add_two_number(int a, int b)
{
     return a + b;
}

int call_func(int (*ptr_func)(int, int), int a, int b)
{
    return ptr_func(a, b);
}

2.The second is using the normal function call:

#include <stdio.h>

int add_two_number(int a, int b);
int call_two_number(int a, int b);

int main (int *argc, char *argv[])
{
    printf("%d", call_two_number(5, 9));

    return 0;
}

int add_two_number(int a, int b)
{
    return a + b;
}

int call_two_number(int a, int b)
{
    return add_two_number(a, b);
}

These two function do simple math addition between two numbers and these two function also work correctly as i expected.

My question is what is the difference between those two? and when we use callback instead of normal function ?

Upvotes: 5

Views: 4414

Answers (6)

Humpity
Humpity

Reputation: 153

A lot of answers stem from common implementations. I'll try to give a viewpoint of when callbacks first appeared.

What is the difference between those two?
Just some level of indirection.

And when we use callback instead of normal function ?
Callbacks appeared when Event Driven systems (like widgets in windows) became popular. You'd get an event (a trigger) and either the callback (a reference to the function) would be embedded in the event interrupt code, or for earlier systems, some other code block would decide which function to call. In either case, the term 'callback' was coined to indicate that this was the function to callback in response to the event.

Callbacks are useful if they are pointers because you can conveniently change them (to another set of functions) but you don't neccessarily have to use them this way. If your main program was some sort of a switch responding to an event, then you could refer either of your versions as 'callback' functions.

Upvotes: 0

Selenimoon
Selenimoon

Reputation: 322

One usage of callback functions is Inversion of Control. Say you dont have a libary whose functions you call but a framework which does most of the stuff and you just add functions to 'fill in the holes'. You pass callback functions to the framework so that it knows where to call back :)

The callback function can be exchanged later and you have a nice abstraction from framework functionality and your own.

Upvotes: 1

Daniel Rudy
Daniel Rudy

Reputation: 1439

Callback functions are used when the function to be called isn't known at compile time. An example is a generic audit routine that is done in some library but the actual cleanup routine is a function in your program.

Another use of callback functions (or function pointers, in the case of the next example) is to have an array of function pointers, or an array of structures that contain function pointers. Different functions can get called just by changing the index into the array when the call needs to happen. An example of this is device drivers. The kernel interface uses the same structure for most devices and such most of the same function calls. Using function pointers, an open call on a file routes though the vnode system while an open call on a device routes through the device driver. This allows an easy way to map function calls without using switch statements or large if-then-else chains. It also allows, on the fly, function calls to be added and removed as kernel modules are loaded and unloaded (in the case of device drivers).

Upvotes: 1

cfz42
cfz42

Reputation: 384

My question is what is the difference between those two?

The former version is much more modular than the latter, ie: let's say you want to implement a simple calculator. The first solution makes it easy to code several "operators" which you will pass to call_func, depending on which one you need.

Example:

#include <stdio.h>

int add_two_number(int a, int b);
int sub_two_number(int a, int b);
int call_func(int (*ptr_func)(int, int), int a, int b);

int main (int *argc, char *argv[])
{
     if (argv[1][0] == '+')
         printf("%d\n", call_func(add_two_number, 5, 9));
     else if (argv[1][1] == '-')
         printf("%d\n", call_func(sub_two_number, 5, 9));

     return 0;
}

int add_two_number(int a, int b)
{
     return a + b;
}

int sub_two_number(int a, int b)
{
     return a - b;
}

int call_func(int (*ptr_func)(int, int), int a, int b)
{
    return ptr_func(a, b);
}

In this particular case, there isn't much benefit from using function pointers instead of plain function calling, but often it can help you write cleaner code (as opposed to multiple if).

When we use callback instead of normal function?

For the most part, you'll use them when you want modularity. If you find yourself writing 4 functions with the same loop or/and conditions, with only a function differing from each other, you should use function pointers. They are also used with the qsort function to define your own sorting rules. You also find function pointers when dealing with external libraries, such as GLFW that uses them for (amongst other things) defining your own functions when you press a key: see this example.

Upvotes: 0

Marc B
Marc B

Reputation: 360572

callbacks give you a layer of abstraction, allowing you disassociate the act of calling a function, from having to know the NAME of the function that it needs to be called with. e.g. they let you write "generic" functions

function do_something(pointer foo) {
}

Let's say this "do_something" function is called a LOT in your problem, and it needs to "call back" to your program for more data.

do_something(&callback_func_number_1);
do_something(&callback_func_number_2);

etc..

One single function, doing whatever it has to, using a callback to request whatever it needs to.

By comparison, with direct calling, you'd need a specific do_something for EVERY variation you have:

do_something_and_call_data_from_func1() { ... }
do_something_and_call_data_from_func2() { ... }

Upvotes: 1

Dark Falcon
Dark Falcon

Reputation: 44181

A callback is used when you do not know what function you want to call at the place where the call is made. For example, what if you wanted to subtract two numbers also:

#include <stdio.h>

int add_two_number(int a, int b);
int sub_two_number(int a, int b);
int call_func(int (*ptr_func)(int, int), int a, int b);

int main (int *argc, char *argv[])
{
     // Here is where we decide what the function should do for the first call
     printf("%d", call_func(add_two_number, 5, 9)); 
     // Here is where we decide what the function should do for the second call
     printf("%d", call_func(sub_two_number, 5, 9));
     return 0;
}

int add_two_number(int a, int b)
{
     return a + b;
}

int sub_two_number(int a, int b)
{
     return a - b;
}

int call_func(int (*ptr_func)(int, int), int a, int b)
{
    return ptr_func(a, b); // Here is the place the call is made
}

Callbacks are also useful for decoupling code. Consider a application with several button. Without callbacks, you would have to, in the button code, have some logic to determine what happens when each button is clicked. By using a callback, the button code can remain generic yet each button can still invoke a different action when clicked.

Upvotes: 4

Related Questions