Here is some rather ridiculous
code to demonstrate what a nested, or local, function
would look like in C
(note that GCC
supports this as an extension):
int foo(int fred)
int quux, yoink;
int bar(int barney)
return quux * 2;
yoink = bar(fred + 1);
return (yoink * quux);
The bolded portion of code contains bar, which is our nested function example.
bar can only be called from foo (not exactly - see below about function pointers), but it
can access any local variable of foo, such as quux. Other than
these differences, the nested function is basically like another function.
A nested function seems to be a simple thing to implement -- at first. Here
are the important issues that come up, and some solutions:
- How does bar know where quux is?
- It simply assumes that the immediately preceding stack frame is from foo.
Note that this will fail in any other case (call from function pointer, recursive nested
function, call from another nested function).
- Or, to allow for recursion, some simple state information could be
passed on the stack. As for function pointers, read on...
- You can't take the function pointer of a nested function!
You'd need some state information to know where quux is, so that
the pointer could be used regardless of where it is used, but
a function pointer is too simple for that!
- Ah, but we now consult the info page describing the GNU C Extension
for nested functions.
A little thing called a trampoline is used. Hideous? Yes. Works? Yes,
at least as long as foo doesn't exit. If it does, well, anything can happen.
- That's disgusting. Well, as long as the inner function can't goto the containing one, it should
still be somewhat readable.
- Sorry to disappoint you. GNU C allows the nested function to goto
somewhere in the function containing it, even if it was called from a
function pointer. All the intermediate function calls will simply go away.
Hideous? YES!!! Works? yes. But for the love of God, never
ever ever use this if you plan for another human to understand your code!
Those GCC developers are seriously twisted. What's next? comefrom?