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.
|
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. |
Quote:
Switch/if-then-else do no allow this. |
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) { |
Quote:
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. |
Function pointers are routinely used in two cases:
|
Quote:
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. |
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. |
Quote:
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 |
Quote:
The same document online: http://linux.die.net/man/3/dlopen . |
Quote:
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), 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. |
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. |
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... |
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. |
Quote:
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. |