It was thus said that the Great Sean Conner via cctalk once stated: > It was thus said that the Great Jecel Assumpcao Jr. via cctalk once stated: > > > You can declare > > new variables inside { ... } and they will shadow variables with the > > same name declared outside of these brackets but this has no effect on > > the runtime structures. > > > > Pascal, on the other hand, allows proceedures to be declared inside > > other proceedures and these nested scopes can access stuff declared in > > the more external scopes. > > Yes. You cannot do this in C because unlike Pascal (and I support others > in the Algol family), C allows you to pass functions to other functions via > function pointers. Pascal does not allow this [1], because of exactly this > reason---external scopes. [2] It becomes more difficult to support. Not > impossible, just real ugly (and most likely a special case).
Actually, I want to expand upon this a bit. Given the following hypothetical C code: int do_the_sort(foobar *foo,size_t nfoo,int sort_criteria[]) { qsort( foo, nfoo, sizeof(foobar), int (const foobar *l,const foobar *r) { if (sort_criteria[l->type] < sort_criteria[r->type]) return -1; else if (sort_criteria[l->type] > sort_criteria[r->type]) return 1; return strcmp(l->name,r->name); } ); /* ... rest of code } The anonymous sorting function accesses data in an outer lexical scope, but the issue here is there's an undetermined number of intermediate stack frames between do_the_sort() and the anonymous sort function. A way around this issue (and it's not limited to this pseudo-C but any function that allows nested functions like this) is to have "fat function pointers" that include two pointers---one to the current lexical scope and one to the actual function, so it would probably look like this in an actual implementation: qsort( foo, nfoo, sizeof(foobar), ADDRESS_OF_STACK_FRAME(do_the_sort), int (STACKFRAME *p,const foobar *l,const foobar *r) { if (p->sort_criteria[l->type] < p->sort_criteria[r->type]) ... } ); (plus some magic in calling the anonymous function from qsort(), like setting the stack frame register (EBP on x86, A6 by convention on the 68000, U on the 6809, R12 on the VAX) to the passed in stack frame prior to calling the function so it just works like any other nested function) The harder issue is the following: void set_signal_handlers(int signum,int what_to_do) { void handler(int sig) { if (what_to_do == EXIT) _exit(1); if (what_to_do == LOG) syslog(LOG_DEBUG,"signal %d happened",sig); } signal(signum,handler); } signal() doesn't actually call the locally scoped function---it just does some system magic to have handler() called when SIGINT or SIGTERM is raised. Unlike the anonymous function in do_the_sort(), where it's called during the execution of qsort so the frame for do_the_sort() still exists, here, the frame for seg_signal_handlers() is long gone by the time the local function handler() is called. And this is a *much harder* problem to solve. I really think it's for *this* reason (the handler() example) that C doesn't allow nested functions. -spc (Misses anonymous and nested functions in C, but has learned to work around it)