Hi, Please CC me in any reply. I'm trying to understand how trampolines are managed in gcc, particularly in the context of gcc's compound statements. I understand from section 6.2.4, Storage durations of objects, of the C99 specification, that the lifetime of an object allocated in a block lasts until the end of that block: 4. An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration. 5. For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. I would expect compound statements to act in the same way, but they are a gcc extension [1]. I haven't found a formal specification for them. Is there one? [1] http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html In any case, a simple test appears to comfirm this: $ cat c.c #include <stdio.h> int main (int argc, char *argv[]) { int *f = ({ int foo = 134; &foo; }); int *b = ({ int bar; &bar; }); printf ("%p => %i\n", f, *f); printf ("%p => %i\n", b, *b); return 0; } $ gcc -Wall c.c -o c && ./c 0xbfd02a04 => 134 0xbfd02a04 => 134 F and B get the same address. I observe different behavior, however, with trampolines: trampolines appear to remain valid until at least the end of the function call. Consider: $ cat d.c #include <stdio.h> int main (int argc, char *argv[]) { /* We reference a local variable to ensure that the functions create a trampoline. */ void (*f)(void) = ({ void foo (void) { printf ("%s: %d\n", __func__, argc); } &foo; }); void (*b)(void) = ({ void bar (void) { printf ("%s: %d\n", __func__, argc); } &bar; }); printf ("%p\n", f); f(); printf ("%p\n", b); b(); printf ("&argc: %p\n", &argc); if (argc == 0) return 0; return main (argc - 1, argv); } $ gcc -Wall c.c -o c && ./c 0xbf885532 foo: 1 0xbf885528 bar: 1 &argc: 0xbf885524 0xbf8854c2 foo: 0 0xbf8854b8 bar: 0 &argc: 0xbf8854b4 In this case, the storage does not appear to be reused, even though they are certainly allocated on the stack frame. Can I rely on this behavior? In particular, can I rely on a trampoline staying valid until the enclosing function returns? Is the behavior of trampoline in a compound block specified somewhere? If not, I would like to see the behavior that I have observed be codified as it is useful for creating lambdas in C. Consider: #include <stdlib.h> #include <stdio.h> /* Inspired by <http://groups.google.com/group/comp.lang.c/browse_thread/thread/fd82dc3d97ea87ff/8b01e62f2feae4f0?lnk=gst> Define a nested function in a compound statement and return that function's address. Is this legitimate? The lifetime of an object defined in a compound statement ends at the end of the compound statement. The lambda does not reference any variables in the enclosing function: at most, it references objects in the context in which the lambda was expanded. However, the trampoline is likely allocated on the stack in the compound statement. One would expect that that would have the same lifetime. Emperically (gcc 4.4.3), it doesn't. */ #define lambda(l_ret_type, l_arguments, l_body) \ ({ \ l_ret_type l_anonymous_functions_name l_arguments \ l_body \ &l_anonymous_functions_name; \ }) int main (int argc, char *argv[]) { int array[] = { 4, 3, 1, 2, 5 }; void dump (void) { int i; for (i = 0; i < sizeof (array) / sizeof (array[0]); i ++) printf ("%d ", array[i]); printf ("\n"); } printf ("Initial: "); dump (); /* Ensure that the lambda is a nested function and thus requires a trampoline. */ int comparison = 0; qsort (array, sizeof (array) / sizeof (array[0]), sizeof (array[0]), lambda (int, (const void *a, const void *b), { dump (); printf ("Comparison %d: %d and %d\n", ++ comparison, *(const int *) a, *(const int *) b); return *(const int *) a - *(const int *) b; })); printf ("Sorted: "); dump (); return 0; } Initial: 4 3 1 2 5 4 3 1 2 5 Comparison 1: 4 and 3 3 4 1 2 5 Comparison 2: 2 and 5 3 4 1 2 5 Comparison 3: 1 and 2 3 4 1 2 5 Comparison 4: 3 and 1 3 4 1 2 5 Comparison 5: 3 and 2 3 4 1 2 5 Comparison 6: 3 and 5 3 4 1 2 5 Comparison 7: 4 and 5 Sorted: 1 2 3 4 5 Thanks, Neal P.S. Please CC me in any reply.