Live data from Hacker News

Basics Of Function Pointers In C

denniskubes.com

41–50 of 61 posts

Re: Basics Of Function Pointers In C

#42

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…

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

Re: Basics Of Function Pointers In C

#43
post #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 e…

That makes a lot of sense, thanks!

Re: Basics Of Function Pointers In C

#45
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).

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.

Re: Basics Of Function Pointers In C

#46
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, but it makes more sense to assign it to a void \*. After all, it's a pointer but you don't know the size of the pointed object.

Note: this is not true everywhere since (data) pointers and function pointers can be represented differently, but on a PC it works :)

Re: Basics Of Function Pointers In C

#47

Earlier quoted context omitted.

> 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 */ Bas…

I don't see the need to do the "ret->doThink = null_think;" since you always pass ret to the function. Just call null_think( ret... )

Re: Basics Of Function Pointers In C

#48
post #7

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

Let's look at the signature of qsort() from libc: void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); qsort is a function inside of libc.so. It's already been compiled. It doesn't know about the "compar" pointer you're going to pass it. That function might not even exist yet. qsort doesn't know if you're sorting integers, sorting strings, sorting struct foo which is still bei…

> qsort is a function inside of libc.so. It's already been compiled.

Unfortunately, this is also why it is so damn slow. Try comparing C++ std::sort with C qsort, the performance gap is HUGE. The reason is that the "function pointer" std::sort gets inlined but qsort will actually invoke a function call via function pointer.

If you'd move qsort to a header file as an inline function, the performance problem would go away.

Re: Basics Of Function Pointers In C

#49

Earlier quoted context omitted.

> 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 */ Bas…

Inheritance can be implemented as well:

    typedef struct AdvancedFoo {
      BaseFoo super;
      int a, b, c;
      thinkfunc_t thinkHarder;
    } AdvancedFoo;
Since `super` is the first member in the struct, a pointer to an AdvancedFoo can be used as a pointer to BaseFoo as well:

    AdvancedFoo *advFoo = AdvancedFoo_new();
    advFoo->thinkHarder(advFoo, advFoo->a);

    ((BaseFoo*) advFoo)->doThink(advFoo, some_int_method());
Of course, this inheritance pattern can continue in multiple steps.

Re: Basics Of Function Pointers In C

#50

Good examples and great 'blow by blow' breakdown. This is a really tough concept to learn, and the C syntax gets a little complicated. This was well laid out, readable, and had a good progression of concepts. Well done!

This was one of the toughest things for me to learn in C. I think I had to learn it 3 times before it stuck. As more schools depart from teaching C, it's worthwhile to have simple explanations.
Post reply on HN