Jos*_*hua 50 c gcc goto language-extension
我在C中看到一个程序,其代码如下:
static void *arr[1] = {&& varOne,&& varTwo,&& varThree};
varOne: printf("One") ;
varTwo: printf("Two") ;
varThree: printf("Three") ;
Run Code Online (Sandbox Code Playgroud)
我&&对它的作用感到困惑,因为它左边没有任何东西.它默认评估为null吗?或者这是一个特例吗?
编辑:添加了一些更多信息,以使问题/代码更清楚我的问题.谢谢大家的帮助.这是gcc特定扩展的一个例子.
Kei*_*son 60
它是一个特定于gcc的扩展,一个&&可以应用于标签名称的一元运算符,将其地址作为void*值.
作为扩展的一部分,goto *ptr;允许在何处ptr是类型的表达式void*.
它的记录在这里在GCC手册.
您可以使用一元运算符获取当前函数(或包含函数)中定义的标签的地址
&&.值有类型void *.此值是常量,可以在该类型的常量有效的任何位置使用.例如:Run Code Online (Sandbox Code Playgroud)void *ptr; /* ... */ ptr = &&foo;要使用这些值,您需要能够跳转到一个值.这是通过计算的goto语句完成的
goto *exp;.例如,Run Code Online (Sandbox Code Playgroud)goto *ptr;
void *允许任何类型的表达式.
正如zwol在评论中指出的那样,gcc使用&&而不是更明显,&因为标签和具有相同名称的对象可以同时显示,&foo如果&意为"标签的地址" ,则可能会模糊不清.标签名称占用它们自己的命名空间(不是在C++意义上),并且只能出现在特定的上下文中:由标签语句定义,作为语句的目标goto,或者对于gcc,作为一元的操作数&&.
M.M*_*M.M 16
这是一个gcc扩展,称为"标签为值".链接到gcc文档.
在此扩展中,&&是一个可以应用于标签的一元运算符.结果是类型的值void *.稍后可以在goto语句中取消引用此值,以使执行跳转到该标签.此外,此值允许指针运算.
标签必须具有相同的功能; 或者在封闭函数中,以防代码也使用"嵌套函数"的gcc扩展名.
这是一个示例程序,其中该功能用于实现状态机:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
void *tab[] = { &&foo, &&bar, &&qux };
// Alternative method
//ptrdiff_t otab[] = { &&foo - &&foo, &&bar - &&foo, &&qux - &&foo };
int i, state = 0;
srand(time(NULL));
for (i = 0; i < 10; ++i)
{
goto *tab[state];
//goto *(&&foo + otab[state]);
foo:
printf("Foo\n");
state = 2;
continue;
bar:
printf("Bar\n");
state = 0;
continue;
qux:
printf("Qux\n");
state = rand() % 3;
continue;
}
}
Run Code Online (Sandbox Code Playgroud)
编译和执行:
$ gcc -o x x.c && ./x
Foo
Qux
Foo
Qux
Bar
Foo
Qux
Qux
Bar
Foo
Run Code Online (Sandbox Code Playgroud)