desigual - ¿Por qué GCC define el operador unario ''&&'' en lugar de solo usar ''&''?
operador in en python (2)
GCC agregó esta extension para usarse en la inicialización de una matriz estática que servirá como una tabla de salto:
static void *array[] = { &&foo, &&bar, &&hack };
Donde foo
, bar
y hack
son etiquetas. Luego se puede seleccionar una etiqueta con indexación, como esta:
goto *array[i];
Norma dice que
C11: 6.2.1 Alcances de los identificadores (p1):
Un identificador puede denotar un objeto ; Una función; una etiqueta o un miembro de una estructura, unión o enumeración; un nombre typedef; un nombre de etiqueta ; un nombre de macro o un parámetro macro.
Además dice en la sección 6.2.3:
Si más de una declaración de un identificador particular es visible en cualquier punto de una unidad de traducción, el contexto sintáctico desambigua los usos que se refieren a diferentes entidades. Por lo tanto, hay espacios de nombres separados para varias categorías de identificadores, como sigue :
- nombres de etiquetas (desambiguados por la sintaxis de la declaración y uso de la etiqueta);
- las etiquetas de estructuras, uniones y enumeración (desambiguadas siguiendo cualquier 32) de las palabras clave
struct
,union
oenum
);- los miembros de estructuras o sindicatos; cada estructura o unión tiene un espacio de nombres separado para sus miembros (desambiguado por el tipo de expresión utilizada para acceder al miembro a través del operador
->
);- todos los demás identificadores, denominados identificadores ordinarios (declarados en declaradores ordinarios o como constantes de enumeración).
Esto significa que un objeto y una etiqueta se pueden denotar con el mismo identificador . En este punto, para que el compilador sepa que la dirección de foo
es la dirección de una etiqueta, no la dirección de un objeto foo
(si existe), GCC definió el operador &&
para la dirección de la etiqueta.
Como se discutió en esta pregunta , GCC define un operador unario no estándar &&
para tomar la dirección de una etiqueta.
¿Por qué define un nuevo operador, en lugar de usar la semántica existente del operador &
, y / o la semántica de las funciones (donde foo
y &foo
proporcionan la dirección de la función foo()
)?
Los nombres de etiquetas no interfieren con otros identificadores, ya que solo se usan en gotos. Una variable y una etiqueta pueden tener el mismo nombre, y en el estándar C y C ++ siempre queda claro en el contexto lo que se quiere decir. Así que esto es perfectamente válido:
name:
int name;
name = 4; // refers to the variable
goto name; // refers to the label
La distinción entre & y && & se necesita para que el compilador sepa qué tipo de nombre esperar:
&name; // refers to the variable
&&name; // refers to the label