I saw a program in C that had code like the following:
static void *arr[1] = {&& varOne,&& varTwo,&& varThree}; varOne: printf("One") ; varTwo: printf("Two") ; varThree: printf("Three") ;
I am confused about what the &&
does because there is nothing to the left of it. Does it evaluate as null by default? Or is this a special case?
Edit: Added some more information to make the question/code more clear for my question. Thank you all for the help. This was a case of the gcc specific extension.
One of the most common fox vocalizations is a raspy bark. Scientists believe foxes use this barking sound to identify themselves and communicate with other foxes. Another eerie fox vocalization is a type of high-pitched howl that's almost like a scream.
Speaking of the meaning of the song, Vegard characterizes it as coming from "a genuine wonder of what the fox says, because we didn't know". Although interpreted by some commentators as a reference to the furry fandom, the brothers have stated they did not know about its existence when producing "The Fox".
WHAT DOES THE FOX SAY? is a picture book version of the lyrics to the catchy pop song and music video by Norwegian pop duo Ylvis. YouTube named \"The Fox (What Does the Fox Say?)\ " its Top Video of 2013, as it received more than 200 million global views.
It's a gcc-specific extension, a unary &&
operator that can be applied to a label name, yielding its address as a void*
value.
As part of the extension, goto *ptr;
is allowed where ptr
is an expression of type void*
.
It's documented here in the gcc manual.
You can get the address of a label defined in the current function (or a containing function) with the unary operator
&&
. The value has typevoid *
. This value is a constant and can be used wherever a constant of that type is valid. For example:void *ptr; /* ... */ ptr = &&foo;
To use these values, you need to be able to jump to one. This is done with the computed goto statement,
goto *exp;
. For example,goto *ptr;
Any expression of type
void *
is allowed.
As zwol points out in a comment, gcc uses &&
rather than the more obvious &
because a label and an object with the same name can be visible simultaneously, making &foo
potentially ambiguous if &
means "address of label". Label names occupy their own namespace (not in the C++ sense), and can appear only in specific contexts: defined by a labeled-statement, as the target of a goto
statement, or, for gcc, as the operand of unary &&
.
This is a gcc extension, known as "Labels as Values". Link to gcc documentation.
In this extension, &&
is a unary operator that can be applied to a label. The result is a value of type void *
. This value may later be dereferenced in a goto
statement to cause execution to jump to that label. Also, pointer arithmetic is permitted on this value.
The label must be in the same function; or in an enclosing function in case the code is also using the gcc extension of "nested functions".
Here is a sample program where the feature is used to implement a state machine:
#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; } }
Compiling and execution:
$ gcc -o x x.c && ./x Foo Qux Foo Qux Bar Foo Qux Qux Bar Foo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With