在閱讀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