gcc 拡張を使うと、関数の中に関数を定義することができる。これを利用する
と C でもクロージャが使えることを少し前に知ったが、
loading...
ようやく理解できた…気がする。
クロージャとは
C 言語のコールバック関数に近いが、引数以外の変数を自身が定義された静的
スコープで解決することが最大の特徴。
…だと理解しています。^^;
コーディング例
#include <stdio.h>
/* 任意の関数 func を n 回実行するだけのライブラリ関数 */
void
dolist(void (*func)(void), int n)
{
int i;
for(i = 0; i < n; i++) {
func();
}
return;
}
int
main(void)
{
int level = 0;
void lambda(void)
{
level++;
}
printf("%d\n", level);
dolist(lambda, 1);
printf("%d\n", level);
dolist(lambda, 2);
printf("%d\n", level);
dolist(lambda, 3);
printf("%d\n", level);
return 0;
}
結果
0
1
3
6
Solaris9 の /usr/local/bin/gcc で確認した。
dolist は渡された処理(lambda)を、指定された回数分実行するだけのライブラ
リ関数。
ユーザ(main)は処理内容を、自分の静的スコープの中で自由に定義することが
できる。level を外部変数にしなくて良い点が素晴らしい。狭いスコープ大事。
lambda() を nm で確認したところ、t マークが付いていた。lambda() はスタッ
クに展開されているわけではなく、static な関数として定義されているという
こと。
lambda() と level の関係はどうなっているんだろう?