Mi sono imbattuto in un pezzo di codice void *p = &&abc;
. Qual è il significato di &&
qui? Conosco i riferimenti rvalue ma penso che &&
usati in questo contesto siano diversi. Cosa &&
indica in void *p = &&abc;
?
Mi sono imbattuto in un pezzo di codice void *p = &&abc;
. Qual è il significato di &&
qui? Conosco i riferimenti rvalue ma penso che &&
usati in questo contesto siano diversi. Cosa &&
indica in void *p = &&abc;
?
Risposte:
&&
è l'estensione di gcc per ottenere l'indirizzo dell'etichetta definita nella funzione corrente.
void *p = &&abc
è illegale nello standard C99 e C ++.
Questo si compila con g ++.
void*
.
__forceinline
? __declspec(naked)
? Uno dei miei MSVCisms preferiti è:, template<typename T> class X { friend T; }
che non è C ++ 03 non valido.
Questo è l'indirizzo di un'etichetta ed è una funzionalità specifica di GCC .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Avresti potuto capirlo da solo testando:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
In tal caso GCC dice:
errore: etichetta "a" utilizzata ma non definita
Devi conoscere l'assemblatore per capirlo veramente, ma cercherò di spiegarti cosa significa un indirizzo di un'etichetta.
Dopo che il sistema operativo ha caricato il file .exe dal disco, un componente del sistema operativo chiamato "il caricatore" (Windows ha il "caricatore PE", linux ha "caricatore ELF" o forse anche altri, se sono compilati nel kernel), esegue una "virtualizzazione" di quel programma, trasformandolo in un processo.
Questo processo pensa che sia l'unico nella RAM e abbia accesso all'intera RAM (ovvero 0x00000000-0xFFFFFFFF su una macchina a 32 bit).
(quanto sopra è solo una breve panoramica di quello che sta succedendo, devi davvero imparare il montaggio per capirlo appieno, quindi abbi pazienza)
Ora, l'etichetta in un codice sorgente è fondamentalmente un indirizzo. "goto label;" non fa nient'altro che un salto a quell'indirizzo (pensa al puntatore dell'istruzione in assembly). Questa etichetta memorizza questo indirizzo RAM ed è così che puoi trovare quell'indirizzo.
Dopo aver appreso ASM, ti renderai conto che quell'indirizzo punta a un'istruzione all'interno della .text
sezione dell'eseguibile. La .text
sezione è quella che contiene il codice (binario) del programma da eseguire.
Puoi ispezionarlo con:
objdump -x a.out
Come descritto in GCC , puoi usarlo per inizializzare una tabella di salto. Alcuni generatori di scanner come re2c (vedi il -g
parametro) lo usano per generare scanner più compatti. Forse c'è anche un generatore di parser che utilizza la stessa tecnica.