接着上一篇
接下来,添加一下参数看看
int main(){
int dmy = 256;
int val = 10;
const char *fmt = "val = %d\n";
void (^blk)(void) = ^{
printf(fmt,val);
};
val = 2;
fmt = "These value were changed. val = %d\n";
blk();
return 0;
}
通过之前的clang命令编译一下,得到以下的代码
首先看一下相同的部分,从上面可以看出来__main_block_desc_0和__block_impl是相同,然后看一下不同的地方__main_block_impl_0的声明以及初始化;
声明部分可以看到,之前使用的自动变量通过block语法作为成员变量追加到__main_block_impl_0结构体中,__main_block_impl_0结构体的成员变量类型的声明与自动变量的类型完全相同。注意,Block语法表达式中没有用到的自动变量不会被追加。
下面是初始化该结构体实例的构造函数的差异:
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags=0) : fmt(_fmt), val(_val)
在初始化结构体实例时,根据传递给构造函数的参数对由自动变量追加的成员变量进行初始化。
接下里时使用Block的匿名函数的实现。
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
const char *fmt = __cself->fmt; // bound by copy
int val = __cself->val; // bound by copy
printf(fmt,val);
}
之前声明定义的__main_block_impl_0结构体实例的成员变量的自动变量被使用到了Block语法表达式中。
总的来说,截获到的自动变量作为成员变量被追加到__main_block_impl_0结构体中,在Block语法表达式执行时,再赋值给与之前相同表达式的自动变量。