Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Function Pointers in C are Underrated (vickychijwani.github.com)
19 points by vickychijwani on March 22, 2012 | hide | past | favorite | 32 comments


The linux kernel has a cool linked list implementation for purposes like this, which IMHO is much prettier. Essentially you put a struct list (or hlist) inside of a struct you use in a list. This struct can be a simple pointer to data, or a full struct itself. Whatever. Then the list macros and functions just work on your data structure.

Implementation details here: http://lxr.linux.no/linux+v3.3/include/linux/rculist.h (also look up list.h).

My favorite part is wrapping your head round the container_of macro central to this. ( http://lxr.linux.no/linux+v3.3/tools/perf/util/include/linux... )

Not that function pointers aren't neat or useful, but sometimes there are other cool solutions too :)


The author claims you might know it as a lambda or anonymous function in other languages, but I think function pointers come up short in comparison.

Function pointers can't capture variables from surrounding scopes and so can't depend on runtime values in any easy or safe way.

Just try emulating the following with function pointers:

  def incrementor(n: Int) = (x:Int) => x + n
Sure you could add another input parameter for the C function pointer, but then you couldn't use it anywhere an arity-1 function is required.


So, with a clever use of a macro (and assuming you use reference-counted smart pointers or have another way of persisting variables at that time on the stack), you can totally make a fire-and-forget closure in C++. Our solution involved declaring inline classes with some minor stringification magic to guarantee uniqueness.


Yep, there are some neat ways of emulating the capture, I didn't mean to imply it was impossible - just beyond what workaday programmers like me are willing to do :)


sigh

FTA: The point was not to go into the nuances of closures and lambdas, but only to highlight the basic similarity between function pointers / lambdas / anonymous functions.


I don't think my comment is sigh worthy really, because the article says you "might know it by the name 'lambda' or ... 'anonymous function'. Now "know it by the name" implies equality/equivalence at least to me (two names for the same referent). I guess it was just a poor choice of words, but that was my point to begin with.


> I guess it was just a poor choice of words, but that was my point to begin with.

This is all called being pedantic. The idea was sound, and, let's be honest, unless you are completely obtuse (and, just to be clear, I don't think you are), I can guess that you understood what he was trying to say. But, you still had to provide a correction.

It's not you. You aren't the only one to do it here. By our very nature, hackers can be very pedantic.

Next time you read an article, and you have the sudden urge to say "Actually..." to correct a single thing, spend a moment to make sure you understand the context. What's the real idea?

Not everyone is going to be an excellent writer. Let's focus on the message, not the poor choice of words. =)


C function pointers are prime citizens for 42 years. Nobody underrates them. 'cdecl' is a fun way to learn all about them.

C++ 's inline templates beat them in performance though.


This should probably be called "Function pointers in C are AWESOME". because they are. Function Pointers are basically C's implementation for callbacks too! There are some awesome things people can do with fp's, and i especially like C++'s use of function pointers and function objects with respect to the STL algorithms and the use of tr1::bind and std::not1 in the functional header. Cool Stuff!


I don't quite understand what is meant by this. Function pointers are not "underrated"; that implies that it is lower or higher than something. Being the only way to perform an indirect branch in C, it's not really something you rate. It just is.


I interpret the statement as being closer to "function pointers are under-discussed".


Indeed. While someone might talk about lambda functions very early into a discussion of Ruby, Python, etc., pointers-to-functions in C are almost never discussed in basic Computer Science.


Through the title, I'm just trying to point out that function pointers are not as well-known in C as in other languages. Programmers should recognize when and how to use them effectively.


Not as well known to C programmers, or not as well known to programmers who don't program C? I don't know a single C programmer that doesn't regularly use function pointers.


Being a student who's been in the process of learning C over the past 3 years, I for one have not come across many examples of function pointers in actual use, apart from the standard library functions qsort and bsearch.


Interesting. Function pointers are powerful, but are hardly a replacement for closures.


No harm. :)

If you want a good example of where they're useful, write the interpreter loop for a simple 3-byte wordsize VM.

To expand on that, make an array of function pointers corresponding to your opcodes. Have the eval() function for a bytecode instruction use the first byte of the bytecode as the array index, and then call the function pointer at that position with the other two bytes as arguments. It's a pretty solid use case.

Also, you're not strictly incorrect--the function pointer does "close over" the execution environment of the system at that time, though that's more a feature of C and globals and pointer arithmetic than anything else. ;)


I'm not sure that closing over only global really counts...


Yes, I suppose it doesn't, as you can't really freeze the execution state (or the relevant parts of it) for the use of the closure--e.g., somebody else can change the memory values before your code gets run and so you act on stale data. :(


A lot of people here have pointed out that closures are not the same as function pointers in C, and for that I thank them. I have added that note to the blog post (it should be up on GitHub shortly), but I would also like to say that the reason for introducing function pointers in that way was to establish a sense of familiarity for those coming from Ruby / Python / JavaScript, who are not well-acquainted with their use in C.


If you know Python / Ruby / Lisp, you might know it by the name ‘lambda’, or if you come from a JavaScript background, you might’ve used it under the name ‘anonymous function’.

This is false. Lambdas capture context; pointed-to functions i C do not.


I believe it is closures that capture context, lambdas are just anonymous functions, see:

http://en.wikipedia.org/wiki/Anonymous_function

vs

http://en.wikipedia.org/wiki/Closure_%28computer_science%29

A lambda function with all its variables bound is a closure iirc.


FTA: The point was not to go into the nuances of closures and lambdas, but only to highlight the basic similarity between function pointers / lambdas / anonymous functions.


Equating function pointers with closures in the second paragraph isn't a good start…


At the most basic level, though, the comparison remains valid, doesn't it? That is all I'm trying to highlight.


No. Maybe you're thinking of anonymous functions? A closure binds a function to its scope. https://en.wikipedia.org/wiki/Closure_%28computer_science%29


The fact that it can be used where other languages would use closures doesn't make them equal, and the language here is pretty definite, you're not using "similar", "like" or "can stand in for"… I can do a tree with an array, that doesn't make them equal.

I don't want to sound too harsh, I'm just noting that any blog post that starts out like that is a bit likely to be instantly discarded by some people. And will confuse others later on when they want to learn about closures…


> At the most basic level, though, the comparison remains valid, doesn't it?

Given that function pointers can't close over variables in the environment, it's a fairly tenuous comparison.

The ability to pass function around is different from the ability of functions to close over their environment. When people talk about closures and their power, they're generally talking about the latter, not the former, at least in my experience.


No, not really. Closures... close on variables, function pointers, are just pointers to functions.

What you are saying is sort of like saying that Classes and Objects are equivalent, creating a closure creates an instance, wheras a function pointer just references the canonical code.

Also, don't undervalue anonymous local functions, which is another thing that full closures have over C99 functions.


Function pointers in C are like salt. Use them sparingly and you can greatly improve the readability and size of your code, use too many of them and you'll end up spoiling the broth and it will become a terrible mess.


TLDR: You can write a comparator function and use it like with C's 'qsort'.


Clear and easily readable C code is underrated.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: