Je suis tombé sur un morceau de code void *p = &&abc;
. Quelle est la signification d' &&
ici? Je connais les références rvalue mais je pense &&
qu'utilisé dans ce contexte est différent. Qu'est-ce que cela &&
indique void *p = &&abc;
?
Je suis tombé sur un morceau de code void *p = &&abc;
. Quelle est la signification d' &&
ici? Je connais les références rvalue mais je pense &&
qu'utilisé dans ce contexte est différent. Qu'est-ce que cela &&
indique void *p = &&abc;
?
Réponses:
&&
est l'extension de gcc pour obtenir l'adresse de l'étiquette définie dans la fonction courante.
void *p = &&abc
est illégal dans les standards C99 et C ++.
Cela compile avec g ++.
void*
.
__forceinline
? __declspec(naked)
? Un de mes MSVCism préférés est:, template<typename T> class X { friend T; }
qui est invalide C ++ 03.
C'est l'adresse d'un label et c'est une fonctionnalité spécifique à GCC .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Vous auriez pu le découvrir vous-même en testant:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
Dans ce cas, GCC dit:
erreur: étiquette 'a' utilisée mais non définie
Vous devez connaître l'assembleur pour vraiment comprendre cela, mais je vais essayer de vous expliquer ce que signifie une adresse d'étiquette.
Une fois que le système d'exploitation a chargé le fichier .exe à partir du disque, un composant du système d'exploitation appelé "le chargeur" (Windows a le "PE Loader", Linux a "ELF loader" ou peut-être même d'autres, s'ils sont compilés dans le kernel), il fait une "virtualisation" de ce programme, le transformant en processus.
Ce processus pense qu'il est le seul dans la RAM et qu'il a accès à toute la RAM (c'est-à-dire 0x00000000-0xFFFFFFFF sur une machine 32 bits).
(ce qui précède n'est qu'un bref aperçu de ce qui se passe, vous devez vraiment apprendre l'assemblage pour le comprendre pleinement, alors soyez avec moi)
Maintenant, l'étiquette dans un code source est essentiellement une adresse. "goto label;" ne fait rien d'autre qu'un saut vers cette adresse (pensez au pointeur d'instruction dans l'assemblage). Cette étiquette stocke cette adresse RAM, et c'est ainsi que vous pouvez trouver cette adresse.
Après avoir appris l'ASM, vous vous rendrez compte que cette adresse pointe vers une instruction dans la .text
section de l'exécutable. La .text
section est celle qui contient le code (binaire) de votre programme à exécuter.
Vous pouvez l'inspecter avec:
objdump -x a.out
Comme décrit dans GCC , vous pouvez l'utiliser pour initialiser une table de saut. Certains générateurs de scanners comme re2c (voir le -g
paramètre) l'utilisent pour générer des scanners plus compacts. Peut-être qu'il existe même un générateur d'analyseur utilisant la même technique.