曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5807|回复: 2
打印 上一主题 下一主题

GNU 内嵌函数(Nested Functions)

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2008-11-18 22:35:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
A nested 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 named square, and call it twice:   

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

嵌套函数被定义在另外一个函数里面(嵌套函数不支持 GNU C++)。在上面的代码中 square 函数在 foo 函数中定义。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2008-11-19 13:53:22 | 只看该作者
The nested function can access all the variables of the containing function that are visible at the point of its definition.
For example, here we show a nested function which uses an inherited variable:

嵌套函数可以访问所有“包含函数”里在定义处可见的变量。下面的代码展示了嵌套函数使用了传入的变量:

void bar(int *array, int offset, int size);

int main()
{
    int i = 20;
    int j = 15;
    int k = 10;
    int *ptr = &k;

    bar( ptr, i, j);

    return 0;
}

void bar(int *array, int offset, int size)
{
    int result;
       
    int access(int *array, int index)
    { return (*array + offset + index); }
   
    int see( int val )
    { printf("%d",val); }
       
    int i;
   
    for(i = 0; i < size; i++)
    {
        result = access(array,i);
        printf("%d  ",result);
    }
   
    printf("\\n");

}

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
板凳
 楼主| 发表于 2008-11-19 20:08:40 | 只看该作者
A nested function is a function defined inside another function. (Nested functions are not supported for GNU C++.) The nested function's name is local to the block where it is defined. For example, here we define a nested function named square, 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 containing function that are visible at the point of its definition. This is called lexical scoping. For example, here we show a nested function which uses an inherited variable named offset:

     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 places where variable definitions are allowed; that is, in any block, mixed with the other declarations and statements in the block.

It is possible to call the nested function from outside the scope of its name 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 function intermediate receives the address of store as an argument. If intermediate calls store, the arguments given to store are used to store into array. 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 the containing function has exited, all hell will break loose. If you try to call it after a containing scope level has exited, and if it refers to 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 function does not refer to anything that has gone out of scope, you should be safe.

GCC implements taking the address of a nested function using a technique called trampolines. 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 containing function, provided the label was explicitly declared in the containing function (see Local Labels). Such a jump returns instantly to the containing function, exiting the nested function which did the goto 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 from access
         if it detects an error.  */
      failure:
       return -1;
     }

A nested function always has no linkage. Declaring one with extern or static is erroneous. If you need to declare the nested function before its definition, use auto (which is otherwise meaningless for 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];
         }
       /* ... */
     }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 11:04 , Processed in 0.081576 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表