当C中没有左侧时,&&运算符会做什么?

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 *.此值是常量,可以在该类型的常量有效的任何位置使用.例如:

void *ptr;
/* ... */
ptr = &&foo;
Run Code Online (Sandbox Code Playgroud)

要使用这些值,您需要能够跳转到一个值.这是通过计算的goto语句完成的goto *exp;.例如,

goto *ptr;
Run Code Online (Sandbox Code Playgroud)

void *允许任何类型的表达式.

正如zwol在评论中指出的那样,gcc使用&&而不是更明显,&因为标签和具有相同名称的对象可以同时显示,&foo如果&意为"标签的地址" ,则可能会模糊不清.标签名称占用它们自己的命名空间(不是在C++意义上),并且只能出现在特定的上下文中:由标签语句定义,作为语句的目标goto,或者对于gcc,作为一元的操作数&&.

  • 如果你想知道,扩展使用`&& label`而不是更自然的`&label`,因为你可以在同一个函数中同时拥有一个标签和一个同名的变量. (4认同)

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)