先来个例子, C 版的
for_each
结合嵌套函数 (必须存为 .c 文件, 使用 gcc 编译才能通过, g++ 压力大)#include <stdio.h>
void for_each(int* begin, int const* end, void (* fn)(int*))
{
while (begin < end) {
fn(begin++);
}
}
#define ARRAY_SIZE 5
int main(void)
{
int a[ARRAY_SIZE];
int n;
void read(int* x)
{
scanf("%d", x);
}
for_each(a, a + ARRAY_SIZE, read);
scanf("%d", &n);
void add(int* x)
{
*x = *x + n;
}
for_each(a, a + ARRAY_SIZE, add);
void print(int* x)
{
printf("%d ", *x);
}
for_each(a, a + ARRAY_SIZE, print);
printf("end\n");
return 0;
}
add
函数, 它引用了一个局部变量 n
, 是在外层函数 main
中定义的. 而 n
的使用并不在 main
的可控范围内, 也许它绕过 for_each
的栈帧, 再继续向上被 add
引用. 这听起来像魔法一样, 幸而 gcc 是个开源软件, 不必担心使用这个特性时会让自己的灵魂落入某个兼职程序员的邪恶巫师手中. 但是这到底是如何实现的呢? 要我讲解 gcc 源码我还没有这个能力, 不过 gcc 有个功能可以让我们比较方便地窥探出其中的技术内幕$ gcc 源文件 -S -o 目标文件
这样源文件会被编译成汇编指令, 接着分析汇编指令好了.
上面那个例子情况比较复杂, 不妨分析下面这段简短的代码
void func(int a, int* b, int c)
{
int nested(void)
{
return a + c;
}
*b = nested();
}