Using GCC's Nested Functions with Wide Pointers and no Trampolines Martin Uecker, 2026-01-06 Introduction Nested functions are extremely useful, which is why basically any computer language since ALGOL60 has them. Except C. In particular, nested functions are useful to write kernels for passing them to higher-order functions. The kernels can access local state, and this is important because it then does not have to be passed as a void pointer to the higher-order function. void tree_increase_all(tree(int) *t, int increment) { void update(int *value) { (*value) += increment; } tree_walk(t, update); } For very simply nested functions it makes also sense to use a lambda expression, i.e. an anonymous nested function. void tree_increase_all(tree(int) *t, int increment) { tree_walk(t, (void(int *value)){ (*value) += increment); }); } How does this work? The nested function gets passed in a special register ‐ the static chain register ‐ a link to its environment. It can then access the variables of the parent function(s) via this pointer. But how does the calling function know what to pass in the static chain register? The obvious solution is to have this information contained in the function pointer, which would be allowed by the C standard. But on most platform the standard application binary interface (ABI) does not allow this. There are different solutions, as we will see below. GCC supports nested function as an extension (but not lambdas). C++ has lambdas with a different syntax, but those are actually objects where each instance has its own unique type. C++'s lambdas are therefor most useful in when used as argument to template functions. To be able to pass them to a non-template function, its unique type needs to be erased by wrapping it in std::function. Why C++'s lambdas are an ingenious design, but have various properties which make them a terrible fit for C. But this is a story for another day. The Problem with GCC's Nested Functions When creating a po...
First seen: 2026-05-28 03:01
Last seen: 2026-05-28 12:10