What does the && operator do when there is no left side in C?

I saw a C program 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 by what && does because there is nothing left of it. Does it default to null? Or is this a special case?

Edit: Added more information to make the question / code more clear for my question. Thank you all for your help. This was a case of the gcc extension.

+50
c gcc goto language-extension
Sep 06 '16 at 21:09
source share
3 answers

This is a gcc-specific extension, the unary && operator, which can be applied to a label name by assigning its address to void* .

goto *ptr; allowed as part of the extension goto *ptr; , where ptr is an expression of type void* .

The gcc document is described here .

You can get the address of the label defined in the current function (or containing the function) with the unary operator && . The value is of type void * . This value is a constant and can be used wherever a constant of this type is valid. For example:

 void *ptr; /* ... */ ptr = &&foo; 

To use these values, you must be able to switch to one. Done with the computed operator goto, goto *exp; . For example,

 goto *ptr; 

Any expression of type void * allowed.

As zwol notes in a comment, gcc uses && rather than the more obvious & , because a label and an object with the same name can be seen at the same time, making &foo potentially ambiguous if & means "label address". Shortcut names occupy their own namespace (not in the C ++ sense) and can only be displayed in certain contexts: defined using labeled-statement, as the target of the goto operator or for gcc, as the operand of the unary && .

+60
Sep 07 '16 at 0:03
source share

This is the gcc extension, known as Shortcuts 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 can later be dereferenced in the goto to force execution to jump to that label. In addition, pointer arithmetic is allowed for this value.

The label must be in the same function; or in a closing function, if the code also uses the gcc extension of "nested functions".

Here is an example of a program in which this function 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; } } 

Compilation and execution:

 $ gcc -ox xc && ./x Foo Qux Foo Qux Bar Foo Qux Qux Bar Foo 
+16
Sep 07 '16 at 0:03
source share

I don't know any operator that works this way in C. Depending on the context, ampersands in C can mean a lot of different things.

Address-Of Statement

Right before the l value, for example

 int j; int* ptr = &j; 

The ptr code above stores the address j, and in this context, the address of any lvalue is taken. The code below would make sense to me if it were written this way.

 static int varOne; static int varTwo; static int varThree; static void *arr[1][8432] = { { &varOne,&varTwo, &varThree } }; 

Logical and

The logical AND operator is simpler, unlike the operator above, it is a binary operator, that is, it requires a left and right operand. The way this works is to evaluate the left and right operands and return true if both are true or greater than 0 if they are not bool.

 bool flag = true; bool flag2 = false; if (flag && flag2) { // Not evaluated } flag2 = true; if (flag && flag2) { // Evaluated } 

Bitwise And

Another use of ampersand in C is bitwise AND. It is similar to the logical AND operator, except that it uses only one ampersand and performs AND operation at the bit level.

Suppose we have a number, and that it displays the binary representation shown below, the AND operation works like this:

 0 0 0 0 0 0 1 0 1 0 0 1 0 1 1 0 --------------- 0 0 0 0 0 0 1 0 

On C ++, things get complicated. An ampersand can be placed after a type to indicate a reference type (you can think of it as a less powerful but safe form of a pointer), then everything becomes even more complicated with 1) a reference to the value of r, when two ampersands are placed after the type. 2) Universal references, when two ampersands are placed after the type of the template or automatically subtracted type.

I think that your code is probably compiled only in your compiler due to the expansion of some roles. I thought about this https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C , but I doubt it.

-6
Sep 06 '16 at 21:50
source share



All Articles