Live data from Hacker News

Basics Of Function Pointers In C

denniskubes.com

31–40 of 61 posts

Re: Basics Of Function Pointers In C

#31
post #22
post #7

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…

This is the kind of stuff I come to HN for. Thank you for helping me finally realize what .dll's really are.

Re: Basics Of Function Pointers In C

#32
post #7

But why that whole mess with function pointers? Where do they have the key advantage compared to directly calling the function?

You use a function pointer when you don't know at compile time what function you are going to call at runtime. An example is plugins: you load a function from a dll (or shared object) and you get a function pointer.

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

#35

The 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…

There's another interesting discussion here:

http://stackoverflow.com/questions/840501/how-do-function-po...

Re: Basics Of Function Pointers In C

#37

Understanding 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…

Elaborating on the OO bit, as derefr did an excellent job of talking about the usefulness of function pointers in a VM.

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

#38
post #20

Earlier 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).

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.

Re: Basics Of Function Pointers In C

#39
post #4

Now it just needs the matching tutorial on initializing pointers in the data section :-)

Could you please elaborate?

(fitting user name, sir or madam!)

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

#40
post #33

If 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?

You can coerce it to an int with a cast, with some caveats: It is implementation defined whether or not the size of an int is sufficient to store a pointer, and the type lets the compiler know what you want to happen when you operate one it.

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.

Post reply on HN