gcc对C语言的扩展:内嵌函数(Nested Function)

简介:
所谓内嵌函数就是定义于另一个函数内部的函数.(GNU C++不支持内嵌函数) 内嵌函数名在它被定义的块中是局部有效的。例如这里我们定义了一个函数squre并调用了它两次:
foo ( double a, double b )
{
double square (double z) { return z * z; }

return square (a) + square (b);
}
包含内嵌函数的函数内的所有变量对于内嵌函数都是可见的。这称为词法作用域(lexical scoping)。例如这里我们给出一个内嵌函数,它使用了一个继承得到的变量,叫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) ...
}
函数内部,允许变量定义的地方就能定义内嵌函数:也就是说,在任何程序块(block)内,第一条语句之前。从内嵌函数名所在有效域之外通过存储它的地址或者把它的地址传给其他函数来调用它也是可行的:
hack (int *array, int size)
{
void store (int index, int value)
  { array[index] = value; }

intermediate (store, size);

这里,函数store的地址作为参数传给了函数intermediate。如果intermediate调用了store,store的参数就会被存储到array里面了。但是这种方式只用当包含store的包含函数(hack)没有返回时才有效。
如果你在当包含函数已经退出后再通过地址方式来调用内嵌函数, 结果不可预料。 如果当你试着在内嵌函数的包含域退出之后调用它,而它使用了某些已经不可见的变量,你可能很幸运的得到正确结果,但是去冒这种风险并不明智。然而,如果内嵌函数没有使用到任何已经不可见的量则应该是安全的。
GCC使用了称为弹床(tramplines)的技术实现内嵌函数的地址的获取。关于该技术的文章可以在
[url]http://people.debian.org/~aaronl/Usenix88-lexic.pdf[/url] 找到。
如果在包含函数中显式定义了一个标签,一个内嵌函数可以跳转到从包含函数中继承过来的标签处。调用goto进行跳转的内嵌将立刻返回(同时也使得中介函数也返回)到包含函数。例如:
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;
}
一个内嵌函数总是使用文件内部链接方式。声明一个带extern的内嵌函数将产生错误。如果你需要在定义一个内嵌函数前声明它,要使用auto关键字(除此种情况之外,在函数定义时使用auto没有任何意义)。
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];
  }
...
}


     本文转自nathanxu 51CTO博客,原文链接:http://blog.51cto.com/nathanxu/56658,如需转载请自行联系原作者




相关文章
|
16天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
26 0
|
27天前
|
编译器 C语言 C++
【C语言】memset()函数(内存块初始化函数)
【C语言】memset()函数(内存块初始化函数)
26 0
|
27天前
|
编译器 C语言 C++
【C语言】memcpy()函数(内存块拷贝函数)
【C语言】memcpy()函数(内存块拷贝函数)
42 0
|
28天前
|
C语言 C++
【C语言】rand()函数(如何生成指定范围随机数)
【C语言】rand()函数(如何生成指定范围随机数)
16 0
|
2天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
2天前
|
C语言
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
|
3天前
|
存储 C语言
C语言函数的返回值
C语言函数的返回值
7 0
|
3天前
|
C语言 Windows
C语言中的fopen与fclose函数详解
C语言中的fopen与fclose函数详解
11 1
|
3天前
|
C语言
深入理解C语言中的printf函数及数据输出
深入理解C语言中的printf函数及数据输出
13 0
|
16天前
|
程序员 C语言 开发者
C语言库函数 — 字符串函数(含模拟实现字符串函数)
C语言库函数 — 字符串函数(含模拟实现字符串函数)
36 0