跳过导航链接 | |
退出打印视图 | |
Oracle Solaris Studio 12.3:C 用户指南 Oracle Solaris Studio 12.3 Information Library (简体中文) |
2.11.3 does_not_read_global_data
2.11.5 does_not_write_global_data
2.11.26 warn_missing_parameter_info
2.14.5 __FUNCTION__ 和 __PRETTY_FUNCTION__
2.18 对 Intel MMX 和扩展的 x86 平台内部函数的编译器支持
C 编译器可识别称为计算转移 (computed goto) 语句的 C 扩展。使用计算转移 (computed goto) 语句能够在运行时确定分支目标。通过使用 '&&' 运算符可以获取标签的地址,并且可以将标签地址指定给 void * 类型的指针:
void *ptr; ... ptr = &&label1;
后面的 goto 语句可以通过 ptr 转到 label1:
goto *ptr;
由于 ptr 在运行时进行计算,因此 ptr 可以接受作用域内任何标签的地址,而 goto 语句可以转到该位置。
使用计算转移 (computed goto) 语句的一种方法是用于转移表的实现:
static void *ptrarray[] = { &&label1, &&label2, &&label3 };
现在可以通过索引来选择数组元素:
goto *ptrarray[i];
标签的地址只能通过当前函数作用域计算。尝试在当前函数外部获取标签的地址会产生不可预测的结果。
转移表和开关语句的作用相似,但转移表使跟踪程序流更加困难。明显的差别是,开关语句转移目标都在 switch 保留字的正向。使用计算转移 (computed goto) 实现转移表可在正向和反向启用分支。
#include <stdio.h> void foo() { void *ptr; ptr = &&label1; goto *ptr; printf("Failed!\n"); return; label1: printf("Passed!\n"); return; } int main(void) { void *ptr; ptr = &&label1; goto *ptr; printf("Failed!\n"); return 0; label1: foo(); return 0; }
以下示例也使用转移表控制程序流:
#include <stdio.h> int main(void) { int i = 0; static void * ptr[3]={&&label1, &&label2, &&label3}; goto *ptr[i]; label1: printf("label1\n"); return 0; label2: printf("label2\n"); return 0; label3: printf("label3\n"); return 0; } %example: a.out %example: label1
计算转移 (computed goto) 语句的另一个应用是作为线程代码的解释程序。解释程序函数内部的标签地址可以存储在线程代码中以便快速分发。