LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Why do we need Function Pointers in C? (https://www.linuxquestions.org/questions/programming-9/why-do-we-need-function-pointers-in-c-906316/)

meenakshi.khurana 10-04-2011 02:51 AM

Why do we need Function Pointers in C?
 
While exploring function pointers, I get to know that we use function pointers for callback and event driven programming. But so can we use switch and if-else. Can someone please help me understand the benefit of function pointers over switch and if-else except readability.

Proud 10-04-2011 04:21 AM

Extensibility without needing to modify the existing code?
A switch statement can't have new cases added dynamically, something that takes a function pointer keeps on doing the same thing even with a new function being passed.

Sergei Steshenko 10-04-2011 04:23 AM

Quote:

Originally Posted by meenakshi.khurana (Post 4489482)
While exploring function pointers, I get to know that we use function pointers for callback and event driven programming. But so can we use switch and if-else. Can someone please help me understand the benefit of function pointers over switch and if-else except readability.

Function pointer allows you to change function(ality) dynamically, in a running program. A new function(ality) can even be loaded from a file (see 'man dlopen').

Switch/if-then-else do no allow this.

bigearsbilly 10-04-2011 05:07 AM

Well, if you write a library you won't know what function pointers are passed in.
so a switch won't work. Like X libraries for instance.


But you're thinking is pretty wise, function pointers should be avoided if you care about
making your code readable and maintainable. And they are a pain to debug.
I wouldn't use them if I can avoid them because sometimes I have to go back a few months or years and debug my code.
A lot of people may use them because they think it makes them look clever whereas it
actually just makes their code harder to understand...
IMHO
:-)

Code:

int main(int argc, char **argv)  {

        int (* array[]) (const char *, ...) = { printf };
        (array)[0]("I am a smart %s\n", "Alec" );
        return 0;
}


MTK358 10-04-2011 06:48 AM

Quote:

Originally Posted by meenakshi.khurana (Post 4489482)
I get to know that we use function pointers for callback and event driven programming. But so can we use switch and if-else.

No, you can't.

Imagine a hypothetical GUI toolkit where you can create a button and give it a function pointer to be called wen the button is clicked. How is this possible with if/else?

Also, function pointers in C aren't really strange, complicated, or any different from normal pointers. All functions are located at a specific address, and it doesn't matter whether the address being called is hard-coded (like in a "normal" C function call) or stored in a pointer.

sundialsvcs 10-04-2011 06:56 AM

Function pointers are routinely used in two cases:
  1. When a "callback" routine needs to be invoked. The routine being called has no other way to know which routine needs to be called-back.
  2. Object "methods" are implemented as function pointers. When you want to call a particular method of a particular object, you don't know in advance what routine will receive control. (Indeed, that's the point.)

Sergei Steshenko 10-04-2011 10:51 AM

Quote:

Originally Posted by MTK358 (Post 4489623)
... How is this possible with if/else? ...

If we are talking about a GUI toolkit with no on the fly change of functionality, and if we have the GUI toolkit source, it is possible.

Just the button (in your example) source is modified to cover all button instances in particular application, and in every particular instance the needed 'switch' numeric argument is used. I.e. the modified 'button' source will contain code for all possible callbacks in a, say, 'switch' statement body.

The above is an long explanation of that simple fact that 'button' instances can be enumerated.

theNbomr 10-04-2011 12:54 PM

Device drivers use function pointers as part of the device-independence concept. A prescribed set of functions to be called is defined by a class of device. At runtime, the actual functions are bound to the calling calling code, and the handlers that are specific to the actual hardware get invoked.
It is a powerful concept, and like anything powerful, should be used with the accordant cautions and prudence. I see it as one of those things that isn't required frequently, but when it is required, there is generally nothing else that does the job quite as well.

--- rod.

meenakshi.khurana 10-04-2011 11:57 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4489542)
Function pointer allows you to change function(ality) dynamically, in a running program. A new function(ality) can even be loaded from a file (see 'man dlopen').

Switch/if-then-else do no allow this.

Thanks for your reply Sergei... I get to understand the usage of function pointers in callback (when a library function needs to call function in user application like signal, qsort) as well as in loading of new functionality from a file (via dlopen).
Can you please give little more explanation on usage of function pointers in a running program? What i get to understand from your point is we can modify functionality of running C program without being restarting them.... Can you show me some example? Thanks in advance

Sergei Steshenko 10-05-2011 06:26 AM

Quote:

Originally Posted by meenakshi.khurana (Post 4490280)
...
Can you please give little more explanation on usage of function pointers in a running program? What i get to understand from your point is we can modify functionality of running C program without being restarting them.... Can you show me some example? Thanks in advance

At the bottom of 'man 3 dlopen' there is an example program. In that program the library name ("libm.so") is hard-coded, but you can modify the program to use any library, and its name can be input by user, or read from a file, etc. Likewise, the function name ("cos") is hard-coded, and it also can be "variable".

The same document online: http://linux.die.net/man/3/dlopen .

tadevokle 10-06-2011 09:32 AM

Quote:

Originally Posted by meenakshi.khurana (Post 4489482)
While exploring function pointers, I get to know that we use function pointers for callback and event driven programming. But so can we use switch and if-else. Can someone please help me understand the benefit of function pointers over switch and if-else except readability.

Because of practical needs:

Imagine you want to write a simple function which should calculate/approximate the derivative of a function f(x), at a given spot x0. Most logically, and intuitively, the function whose derivative at the spot x0 is to be calculated/approximated, *should* be passed to the function as an argument.

Assuming that the function f takes only one argument and the epsilon is a positive number greater then 0 my take would be something like:

Code:

double derive(double (*f)(double),
              double x0,
              double epsilon)
{
    return ((*f)(x0)-(*f)(x0-epsilon))/(epsilon);
}

I can't imagine a possible way of writing this kind of a function without using pointers. (well, at least without using OOP)

Beside from this example the whole point of writing functions is to make a chunk of code easily reusable. Even if you could emulate the same beaviour with some trickeries using switches and if-else blocks, you would be reinventing the wheel over and over again, because your code wouldn't be capsulated good enough.

theNbomr 10-06-2011 10:35 AM

If one wanted to perform a system reset, typically performed by invoking code at a known, fixed address, how else could that be accomplished in C, without using a function pointer?

--- rod.

meenakshi.khurana 10-07-2011 07:04 AM

Thanks all for your responses...

I have a module whose job is to do packet deciphering and then processing every packet depending upon its type... Currently i am doing this job using switch statement but now i am planning to migrate it to function pointers... and pseudo code for that will be something like:

1) Store packet type (event) and its corresponding handler function (function pointer) in hash
2) Receive packets in infinite loop. Search its type in hash and call corresponding handler

I just need your inputs on this. Will i get any benefits by replacing switch with function pointers in this case...

Proud 10-07-2011 07:28 AM

Seems pointless unless you need to deal with new packet types without creating a new binary. When do you expect any different function pointers will be put in your hash apart from the same current set?

Choosing which function/block of code to execute isn't going to be much different/faster using a switch vs hash, any performance improvement probably should be sought in the individual handler functions/overall code flow & resource management.

johnsfine 10-07-2011 07:37 AM

Quote:

Originally Posted by meenakshi.khurana (Post 4492341)
1) Store packet type (event) and its corresponding handler function (function pointer) in hash
2) Receive packets in infinite loop. Search its type in hash and call corresponding handler

I just need your inputs on this. Will i get any benefits by replacing switch with function pointers in this case...

Do you mean a performance benefit or a code maintenance benefit?

The performance difference should be pretty small compared to the rest of the work the code is doing. That performance difference is the efficiency difference between your hash and whatever lookup table the compiler creates to support the switch statement. Without a lot more info, I wouldn't want to guess which is faster and I don't think it matters much.

The code maintenance benefit would depend on how (and why) you structure item (1) of your plan. If that all happens in one place or there is no good reason for it not to happen in one place, then there is no code maintenance benefit.

In some projects, there may be significant code maintenance benefits to distributing your part (1) so it is associated with event specific code rather than associated with the global dispatch system. In that case, the benefit of the hash over the switch is that you can distribute the code of part (1).

The extreme case of such benefits (matching what earlier posts said or implied about function pointers): You might have the dispatch system and hashing code already written and compiled (in the main executable or .so) and have some new event type introduced at run time (such as when dynamically loading another .so).


All times are GMT -5. The time now is 05:05 PM.