Me encontré con un fragmento de código void *p = &&abc;
. ¿Cuál es el significado de &&
aquí? Sé acerca de las referencias de rvalue pero creo que se &&
usa en este contexto es diferente. ¿Qué &&
indica en void *p = &&abc;
?
Me encontré con un fragmento de código void *p = &&abc;
. ¿Cuál es el significado de &&
aquí? Sé acerca de las referencias de rvalue pero creo que se &&
usa en este contexto es diferente. ¿Qué &&
indica en void *p = &&abc;
?
Respuestas:
&&
es la extensión de gcc para obtener la dirección de la etiqueta definida en la función actual.
void *p = &&abc
es ilegal en los estándares C99 y C ++.
Esto se compila con g ++.
void*
.
__forceinline
? __declspec(naked)
? Uno de mis MSVCisms favoritos es:, template<typename T> class X { friend T; }
que no es válido C ++ 03.
Esa es la dirección de una etiqueta y es una característica específica de GCC .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Podrías haberlo descubierto tú mismo probando:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
En cuyo caso GCC dice:
error: etiqueta 'a' usada pero no definida
Necesita saber ensamblador para entender esto realmente, pero trataré de explicarle qué significa la dirección de una etiqueta.
Después de que el sistema operativo carga el archivo .exe desde el disco, un componente del sistema operativo llamado "el cargador" (Windows tiene el "cargador PE", Linux tiene "cargador ELF" o incluso otros, si están compilados en el kernel), hace una "virtualización" de ese programa, convirtiéndolo en un proceso.
Este proceso piensa que es el único en RAM y tiene acceso a toda la RAM (es decir, 0x00000000-0xFFFFFFFF en una máquina de 32 bits).
(lo anterior es solo una breve descripción de lo que está sucediendo, realmente necesita aprender a ensamblar para comprenderlo completamente, así que tenga paciencia conmigo)
Ahora, la etiqueta en un código fuente es básicamente una dirección. "ir a etiqueta;" no hace nada más que un salto a esa dirección (piense en el puntero de instrucción en ensamblador). Esta etiqueta almacena esta dirección RAM, y así es como puede encontrar esa dirección.
Una vez que haya aprendido ASM, se dará cuenta de que esa dirección apunta a una instrucción dentro de la .text
sección del ejecutable. los.text
sección es la que contiene el código (binario) de su programa para ser ejecutado.
Puede inspeccionar esto con:
objdump -x a.out
Como se describe en GCC , puede usar esto para inicializar una tabla de salto. Algunos generadores de escáneres como re2c (consulte el -g
parámetro) lo usan para generar escáneres más compactos. Tal vez incluso haya un generador de analizador sintáctico que emplee la misma técnica.