pg表达式引擎里面各个表达式的串联是使用goto动态label实现的。
// 定义部分 #if defined(EEO_USE_COMPUTED_GOTO)static const void *const dispatch_table[] = {&&CASE_EEOP_DONE,&&CASE_EEOP_INNER_FETCHSOME,&&CASE_EEOP_OUTER_FETCHSOME,&&CASE_EEOP_SCAN_FETCHSOME,&&CASE_EEOP_INNER_VAR,&&CASE_EEOP_OUTER_VAR,&&CASE_EEOP_SCAN_VAR, ...// 跳转 EEO_CASE(EEOP_OUTER_FETCHSOME){CheckOpSlotCompatibility(op, outerslot);slot_getsomeattrs(outerslot, op->d.fetch.last_var);EEO_NEXT();}// 宏定义 #define EEO_SWITCH() starteval: switch ((ExprEvalOp) op->opcode) #define EEO_CASE(name) case name: #define EEO_DISPATCH() goto starteval #define EEO_OPCODE(opcode) (opcode)#endif /* EEO_USE_COMPUTED_GOTO */#define EEO_NEXT() \do { \op++; \EEO_DISPATCH(); \} while (0)#define EEO_JUMP(stepno) \do { \op = &state->steps[stepno]; \EEO_DISPATCH(); \} while (0)
也就是日常用的比较少的&&操作符。如下:
#include <stdio.h> #include <string.h>enum {ADD,SUB,MUL,DIV,END };int main(int argc,char *argv[]) {static const void *const disptab[] = { &&L_ADD,&&L_SUB,&&L_MUL,&&L_DIV,&&L_END}; int code[] = {ADD,ADD,MUL,MUL,END};int i = 0;int sum = 0;goto *disptab[code[i++]]; L_ADD:sum += 2;goto *disptab[code[i++]]; L_SUB:sum -= 2;goto *disptab[code[i++]]; L_MUL:sum *= 2;goto *disptab[code[i++]]; L_DIV:sum /= 2;goto *disptab[code[i++]]; L_END:printf("sum = %d\n",sum);return 0; }
其等价于switch case,如下:
for() {switch(){case ADD:sum += 2;break;case SUB:sum -= 2;break;case MUL:sum *= 2;break;case DIV:sum /= 2;break;case END:} }
相比来看,速度会更快。