Movatterモバイル変換


[0]ホーム

URL:


Next: ,Previous: Labels as Values,Up: C Extensions


5.4 Nested Functions

Anested function is a function defined inside another function. (Nested functions are not supported for GNU C++.) The nested function'sname is local to the block where it is defined. For example, here wedefine a nested function namedsquare, and call it twice:

     foo (double a, double b)     {       double square (double z) { return z * z; }            return square (a) + square (b);     }

The nested function can access all the variables of the containingfunction that are visible at the point of its definition. This iscalledlexical scoping. For example, here we show a nestedfunction which uses an inherited variable namedoffset:

     bar (int *array, int offset, int size)     {       int access (int *array, int index)         { return array[index + offset]; }       int i;       /*... */       for (i = 0; i < size; i++)         /*... */ access (array, i) /*... */     }

Nested function definitions are permitted within functions in the placeswhere variable definitions are allowed; that is, in any block, mixedwith the other declarations and statements in the block.

It is possible to call the nested function from outside the scope of itsname by storing its address or passing the address to another function:

     hack (int *array, int size)     {       void store (int index, int value)         { array[index] = value; }            intermediate (store, size);     }

Here, the functionintermediate receives the address ofstore as an argument. Ifintermediate callsstore,the arguments given tostore are used to store intoarray. But this technique works only so long as the containing function(hack, in this example) does not exit.

If you try to call the nested function through its address after thecontaining function has exited, all hell will break loose. If you tryto call it after a containing scope level has exited, and if it refersto some of the variables that are no longer in scope, you may be lucky,but it's not wise to take the risk. If, however, the nested functiondoes not refer to anything that has gone out of scope, you should besafe.

GCC implements taking the address of a nested function using a techniquecalledtrampolines. A paper describing them is available as

http://people.debian.org/~aaronl/Usenix88-lexic.pdf.

A nested function can jump to a label inherited from a containingfunction, provided the label was explicitly declared in the containingfunction (seeLocal Labels). Such a jump returns instantly to thecontaining function, exiting the nested function which did thegoto and any intermediate functions as well. Here is an example:

     bar (int *array, int offset, int size)     {       __label__ failure;       int access (int *array, int index)         {           if (index > size)             goto failure;           return array[index + offset];         }       int i;       /*... */       for (i = 0; i < size; i++)         /*... */ access (array, i) /*... */       /*... */       return 0;           /*Control comes here fromaccess         if it detects an error.  */      failure:       return -1;     }

A nested function always has no linkage. Declaring one withextern orstatic is erroneous. If you need to declare the nested functionbefore its definition, useauto (which is otherwise meaninglessfor function declarations).

     bar (int *array, int offset, int size)     {       __label__ failure;       auto int access (int *, int);       /*... */       int access (int *array, int index)         {           if (index > size)             goto failure;           return array[index + offset];         }       /*... */     }

[8]ページ先頭

©2009-2025 Movatter.jp