Sometimes it is a useful sin, many data structure libraries for C use this for:
1) genericity
2) (extreme) speed
It's (unfortunately) impossible for C to equal C++ templates in this: write once, use for multiple datatypes (without macros).
For people who like copy pasting, generic macros is on the horizon for C11, which is rapidly being implemented (and mostly works) for Clang and GCC, the most important compilers. Read more about it here: http://www.robertgamble.net/2012/01/c11-generic-selections.h...
Simply put, it allows to create a small "shim"-macro that detects the type of the input parameters and redirect to an actual function based on type.
What's wrong with that? It allows you to write type-safe sort-of-generic data structures. It's certainly better than 'generic' data structures that work on void*'s.
> Understanding function pointers in C unlocks the ability to write clean, object-oriented code with inheritance (kinda, sorta, shhhh).
People often say this in regards to pointers, or something similar like in the article too, "When understood, function pointers become a powerful tool in the C toolbox.", but often don't explain how/why. In the article the author says that at some indefinite point of time in future they may write about that.
Do you, or anyone, have a link to somewhere not simply explaining the technical side of pointers, but their usage in idealistic and primarily real world examples? Bonus points if it includes indirection, function pointers and other things.
Update: User derefr gave a seemingly great answer below to a similar question like mine.
>> Do you, or anyone, have a link to somewhere not simply explaining the technical side of pointers, but their usage in idealistic and primarily real world examples?
I often use them for parsing json on the fly in an embedded environment with limited ram. Suppose you have a runtime with 4K RAM of which 2K is available, but in comes a string that requires much more space. You can't store the string in RAM, validate it and then use the variables. What I do is parse on the fly and store the variables along with function pointers that need to process them. Once the string has ended and you're sure it's valid and checksummed you process the variables with their function pointers. This technique stretches the length of the message you're able to process, especially for stuff like 32-bit floats that have a larger string than binary representation.
>> "When understood, function pointers become a powerful tool in the C toolbox."
The callback pattern.
I have no idea if I just made that up or if it's a term in use, but it's where I most often find them useful. For instance the interface to libpcap. You can pass libpcap a function to call when it sees network traffic. Without this you would need some sort of polling in your own code. I've seen this in use in a variety of event-driven frameworks written in C.
The other major one I've implemented in the past is thread-pooling with job queues. You can make a queue of jobs that way. Each job is a struct containing a function pointer and a pointer to a struct of arguments. When a thread becomes idle it pulls the job off the queue and calls the function with the given args.
There are probably more. Yes you can kind-of mangle OO out of them, but I prefer the other uses.
So, if I want to create a new BaseFoo, I just call Foo_new() and I'm off to the races; I get back a Foo object that, during my update loop, I can fiddle with:
So, this is very bland, but it gets across the idea that function pointers let me easily override member methods on class instances. You can imagine that, with a little cleverness, you can store arbitrary data into the struct, along with a table of function pointers to instance methods (a virtual function table).
This is a very fun, very deep rabbit hole.
In a lot of ways, you basically fake the type of prototypical inheritance you'd expect from, say, JavaScript.
EDIT:
Elaborating on another point--it's very common to use function pointers in a struct that then gets filled out by a dll or shared library.
For example, let's say that I've got a renderer that draws 3D stuff and conforms to an API. At runtime, I check what driver the user wants to use (software renderer, Direct3D, or OpenGL), and then I fill out the function pointers of that structure to point at the architecture and driver-specific methods I'd like to use.
The rest of my code doesn't change, because it only ever calls the interface exposed by the structure--the actual addresses pointed to by the function pointers are irrelevant.
Ah, but what if the object is handed over to some other deep end of the code? We want to bake the null behavior into it so that any Foo knows how to think itself--calling code just needs to be aware that any Foo object will always have a valid think callback defined.
With great power, etc. etc.