在阅读Erts的代码的时候,尤为是在process_main这个函数的时候。看到一个奇怪的宏叫作NO_JUMP_TABLE,里面定义的数组opcodes[] = { DEFINE_OPCODES };其中DEFINE_OPCODES的定义是以&&开头的标签。数组
以下面的代码例子:函数
#include<string.h> #include<stdlib.h> #include<stdio.h> #define LabelAddr(Addr) &&Addr int main(){ void* opcodes[] = {&&lb_catch_end_y}; opcodes[0] = LabelAddr(lb_catch_end_y); goto *opcodes[0]; printf("Never seen this \r\n"); free(opcodes); return 0; lb_catch_end_y: printf("After goto \r\n"); return 1; }
其中lb_catch_end_y是goto标签,能够使用&&lb_catch_end_y来得到goto标签的地址。经过不断添加goto标签的地址到opcodes数组中,咱们经过直接goto *opcodes[0]来进行跳转,当咱们在运行时更换opcodes[0]中的地址,咱们就会很方便的在这个函数内跳转来跳转去的,而且能够使用整个函数内全部的局部变量。this
那么这东西能够干什么事情呢,经过这东西,咱们就能够用C语言构造出高级语言所具备的尾递归。或者使用这个东西来构造自定义的执行流程,就像Erts的process_main那样的虚拟指令解释器。spa