It's been officially supported in GCC since about a decade ago, I believe. It's not part of the C language, so if you're writing this code, it's no longer C. It also requires executable stacks.
The article indicates its not officially supported, although it could be.
Ian Lance Taylor replied that the behavior is
undefined, but so far stable. His suggestion was
to open a bug and request that this desirable (!!!)
behavior be explicitly permitted.
Because of the way nested functions are implemented in GCC.
If you call a nested function it has to know the frame address of the containing function in order to refer to its local variables. So if you take the address of such a function the program actually receives the address of a "trampoline": a small sequence of instructions which first loads the frame address and then calls the real function.
The trampoline itself is generated dynamically and putting it on the stack turns out to be cheaper than heap allocating it.
> and putting it on the stack turns out to be cheaper than heap allocating it.
Well, more so that C has no concept of the heap. That's entirely contained within the C libraries. So, the language implementation itself can't do heap allocations (at least, not without sacrificing any chance of using it in embedded or kernel dev situations where you don't have heap allocation, or where you need to use custom allocators)
Right. And of course the whole idea is prone to insane amounts of fail.
> Thus, if you access the enclosing environment, you
> must ensure that the lifetime of this lambda is bound by the
> lifetime of the enclosing environment (i.e., until the enclosing
> function returns). This means that if you access local
> variables, bad things will happen. If you don't access local
> variables, you're fine.
Might as well avoid the complications, hoist the function and pass a function pointer with some context (assuming it's needed).
You're not passing a compound statement expression as a function pointer. You are passing the result of the evaluation of that expression --which is a function pointer -- as a function pointer.
They should try to make something syntactically compatible with C++ lambdas. It's annoying that the two languages are more and more incompatible for cosmetic reasons.
That's the definition of a closure. I'm not sure if "lambda" is necessarily synonymous with "closure" or just synonymous with "anonymous function", but lambdas are closures in many languages.
That's slightly sloppy phrasing. It captures it, but it does not duplicate it, so it's lifetime is tied to the stack frame of the function you declared it in.
Anonymous functions are very handy, and I think they should really be taken a step further. There's really no reason why it shouldn't be possible to pass an actual function body where a function pointer is required:
int v[...];
qsort( v, ..., (a, b) { return *(int*)a - *(int*)b } );
Such usage would also have an added benefit of letting the compiler do the type inference for a, b and the return value and not needing to explicitly specify them in qsort() call.
Local functions would be a nice compromise between the unreadable glop that was posted and the need to declare an entirely separate function to execute localized actions.
printf("I am bad and evil %p\n", ({int bad_and_evil(void){return 0;};&bad_and_evil;}));
printf("I am bad and evil2 %d\n", ({0x4FFFFFF;}));
void* result = ({void* bad_and_evil(int dummy){return 0;};&bad_and_evil;});
printf("bad and evil 3 = %p\n", result);
* shudder * Getting a return value from a block, by inserting it in parantheses.
I personally think so, as I think blocks in C are a clumsy way around the issue (probably because C doesn't natively have garbage collection) and it feels natural in go, but I know others will disagree.
Also, I don't think you can make it anonymous, can you?
http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC62