studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones c gcc goto language-extension

programacion - ¿Qué hace un operador && cuando no hay un lado izquierdo en C?



manual de programacion android pdf (3)

Es una extensión específica de gcc, un operador unario && que se puede aplicar al nombre de una etiqueta, obteniendo su dirección como un valor void* .

Como parte de la extensión, goto *ptr; se permite que ptr sea ​​una expresión de tipo void* .

Está documentado here en el manual de gcc.

Puede obtener la dirección de una etiqueta definida en la función actual (o una función que contiene) con el operador unario && . El valor tiene tipo void * . Este valor es una constante y puede usarse siempre que una constante de ese tipo sea válida. Por ejemplo:

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

Para usar estos valores, debes poder saltar a uno. Esto se hace con la instrucción goto calculada, goto *exp; . Por ejemplo,

goto *ptr;

Se permite cualquier expresión de tipo void * .

Como señala zwol en un comentario, gcc usa && lugar de ser más obvio & porque una etiqueta y un objeto con el mismo nombre pueden verse simultáneamente, lo que hace que &foo potencialmente ambiguo si & significa "dirección de etiqueta". Los nombres de etiqueta ocupan su propio espacio de nombres (no en el sentido de C ++) y pueden aparecer solo en contextos específicos: definidos por una declaración etiquetada , como el objetivo de una declaración goto o, para gcc, como el operando de unary && .

Vi un programa en C que tenía un código como el siguiente:

static void *arr[1] = {&& varOne,&& varTwo,&& varThree}; varOne: printf("One") ; varTwo: printf("Two") ; varThree: printf("Three") ;

Estoy confundido acerca de lo que hace el && porque no hay nada a la izquierda del mismo. ¿Se evalúa como nulo por defecto? ¿O es este un caso especial?

Editar: agregué más información para hacer que la pregunta / código sea más claro para mi pregunta. Gracias a todos por la ayuda. Este fue un caso de la extensión específica de gcc.


Esta es una extensión de gcc, conocida como "Etiquetas como valores". Enlace a la documentación de gcc .

En esta extensión, && es un operador unario que se puede aplicar a una etiqueta . El resultado es un valor de tipo void * . Este valor puede luego ser desreferenciado en una declaración goto para hacer que la ejecución salte a esa etiqueta. Además, la aritmética del puntero está permitida en este valor.

La etiqueta debe estar en la misma función; o en una función adjunta en caso de que el código también esté usando la extensión gcc de "funciones anidadas".

Aquí hay un programa de muestra donde la característica se usa para implementar una máquina de estado:

#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; } }

Compilación y ejecución:

$ gcc -o x x.c && ./x Foo Qux Foo Qux Bar Foo Qux Qux Bar Foo


No conozco ningún operador que funcione de esta manera en C. Dependiendo del contexto, el signo y en C puede significar muchas cosas diferentes.

Operador Address-Of

Justo antes de un lvalue, por ejemplo

int j; int* ptr = &j;

En el código anterior, ptr almacena la dirección de j, y en este contexto toma la dirección de cualquier lvalue. El código a continuación, tendría más sentido para mí si estuviera escrito de esa manera.

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

Lógico Y

El operador AND lógico es más simple, a diferencia del operador anterior, es un operador binario, lo que significa que requiere un operando izquierdo y derecho. La forma en que funciona es evaluando el operando izquierdo y derecho y devolviendo verdadero, si ambos son verdaderos, o mayor que 0 si no son bool.

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

Bitwise Y

Otro uso del ampersand en C, está realizando AND a nivel de bit. Es similar al operador AND lógico, excepto que usa solo un signo comercial, y realiza una operación Y en el nivel de bit.

Supongamos que tenemos un número y que se asigna a la representación binaria que se muestra a continuación, la operación AND funciona así:

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

En C ++, las cosas se vuelven más complicadas. El signo & se puede colocar después de un tipo para indicar un tipo de referencia (se puede considerar como un tipo de puntero menos potente pero seguro), luego las cosas se complican aún más con 1) referencia de valor r cuando se colocan dos signos y símbolos un tipo. 2) referencias universales cuando se colocan dos signos y símbolos después de un tipo de plantilla o un tipo deducido automáticamente.

Creo que su código probablemente compila solo en su compilador debido a una extensión de algunos géneros. Estaba pensando en esto https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C pero dudo que ese sea el caso.