But why that whole mess with function pointers? Where do they have the key advantage compared to directly calling the function?
Function pointers are useful anywhere you don't know what function you're going to call until runtime (and yet more useful still when the number of functions you could be calling is unlimited or extensible.) Sure, you can get away with, say, implementing a parser with a big switch statement that calls various parse_this() or parse_that() functions, depending on what kind of token you hit. On the other hand, you could…
Basics Of Function Pointers In C
31–40 of 61 posts
Re: Basics Of Function Pointers In C
#32But why that whole mess with function pointers? Where do they have the key advantage compared to directly calling the function?
When dealing with native code, functions are just piles of instructions in memory (with executable bit set in memory protection) that comes from the "text" section of your binary file. The code is stored in memory and therefore has an address, through which they can be reached.
Re: Basics Of Function Pointers In C
#33Re: Basics Of Function Pointers In C
#34Re: Basics Of Function Pointers In C
#35The article is missing at least one useful thing: how to declare a typedef for a function pointer. This can be used both to avoid error-prone duplication of declarations and to simplify excessively complex declarations. Here's a simple example: http://en.wikipedia.org/wiki/Typedef#Using_typedef_with_func... Here's a more complex example: http://www.devx.com/tips/Tip/13829 Here's a tutorial on how to interpret the com…
http://stackoverflow.com/questions/840501/how-do-function-po...
Re: Basics Of Function Pointers In C
#36Re: Basics Of Function Pointers In C
#37Understanding function pointers in C unlocks the ability to write clean, object-oriented code with inheritance (kinda, sorta, shhhh). With great power, etc. etc.
> 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 t…
So, let's say I have a structure which I will use to represent objects in my game:
typedef void (*thinkfunc_t)(void* self, unsigned int dt);
typedef struct BaseFoo {
float x,y,z;
thinkfunc_t doThink;
} BaseFoo;
void null_think(void* self, unsigned int dt) { return 0; } /* empty think function */
BaseFoo* Foo_new() {
BaseFoo* ret;
ret = calloc(1,sizeof(BaseFoo));
ret->doThink = null_think;
return ret;
}
BaseFoo* Foo_clone( BaseFoo* foo) {
BaseFoo* ret;
ret = Foo_new();
memmove( ret, foo, sizeof(BaseFoo) );
return ret;
}
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: /* update loop snipped for brevity */
BaseFoo* currentFoo;
currentFoo = get_my_foo_from_my_big_foo_list();
currentFoo->doThink(currentFoo, getFrameTimeInMilliseconds());
So, that's kind of cool, but what if I want to create a new, better foo, that actually moves? I do this: void move_think(void* self, unsigned int dt) {
BaseFoo* foo = (BaseFoo*) self;
foo->x += dt;
foo->y += dt;
foo->z += dt;
return 0;
}
typedef BaseFoo MovingFoo;
MovingFoo* MovingFoo_new() {
MovingFoo* ret;
ret = Foo_new();
ret->doThink = move_think;
return ret;
}
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.
Re: Basics Of Function Pointers In C
#38Earlier quoted context omitted.
I committed what I now realize were true crimes against software engineering when I first learned of function pointers.
They can't be any worse than abusing the C preprocessor to implement templates for C code (a sin I committed in college).
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.
Re: Basics Of Function Pointers In C
#39Now it just needs the matching tutorial on initializing pointers in the data section :-)
Could you please elaborate?
I'm guessing he's referring to declaring a global structure or collection of function pointers, and then using #ifdef's and compiler flags to actually assign those function pointers to things that make optimal sense for the architecture.
Or, at runtime (but hopefully before usage!) setting those global function pointers to point at routines optimal for the situation the program is running under--say, setting them to point at an optimized SSE3 vector routine if the CPU supports it.
Maybe that's it?
Re: Basics Of Function Pointers In C
#40If the name of a function is already the memory address of the function, what extra information does the pointer store? Couldn't you just assign the name of the function to, say, an int?
If "foo" is an integer variable, then "foo + 1" returns the integer value of foo + 1, but if "foo" is a pointer, "foo + 1" returns the value of foo + the size of a pointer, for example.
So the pointer does not store any extra information, but the compiler stores and makes use of extra information about the pointer variable (not about the value itself) during compilation.