Me deparei com um pedaço de código void *p = &&abc;. Qual é o significado &&disso? Eu sei sobre referências de rvalue, mas acho que &&usado neste contexto é diferente. O que &&indica em void *p = &&abc;?
Agora imagine como todos seriam melhores programadores se o gcc tivesse -pedantic por padrão. Então as pessoas aprenderiam C em vez de informações irrelevantes sobre gnus.
Lundin
4
Que hack. Se eles inventarem uma nova sintaxe para ponteiros de rótulo, eles também devem inventar um novo tipo para ela em vez de usar void*.
Mark Ransom
1
@Prasoon Saurav: Quem votou negativamente provavelmente desaprova o recurso e está descontando em você.
Chuck
@Lundin: O mesmo pode ser dito da maioria dos compiladores. __forceinline? __declspec(naked)? Um dos meus MSVCismos favoritos é:, template<typename T> class X { friend T; }que é inválido C ++ 03.
Sebastian Mach
O segundo link está morto.
Cœur
96
Como descobrir
Esse é o endereço de um rótulo e é um recurso específico do GCC .
int main(void){void* startp;
s:
startp =&&s;
printf("the assignment above starts at address %p\n", startp);return0;}
Você poderia ter descoberto sozinho testando:
int main(void){void* startp;int a;
startp =&&a;
printf("startp=%p\n", startp);return0;}
Nesse caso, o GCC diz:
erro: rótulo 'a' usado, mas não definido
Sob o capô - montagem
Você precisa conhecer o assembler para realmente entender isso, mas tentarei explicar o que significa o endereço de um rótulo.
Depois que o SO carrega o arquivo .exe do disco, um componente do sistema operacional chamado "o carregador" (o Windows tem o "PE Loader", o linux tem o "ELF loader" ou talvez até outros, se estiverem compilados no kernel), ele faz uma "virtualização" desse programa, transformando-o em um processo.
Este processo pensa que é o único na RAM e tem acesso a toda a RAM (ou seja, 0x00000000-0xFFFFFFFF em uma máquina de 32 bits).
(o texto acima é apenas uma breve visão geral do que está acontecendo, você realmente precisa aprender a montagem para entendê-lo totalmente, então tenha paciência comigo)
Agora, o rótulo em um código-fonte é basicamente um endereço. "goto label;" não faz nada mais do que um salto para aquele endereço (pense no ponteiro de instrução no assembly). Esta etiqueta armazena esse endereço de RAM e é assim que você pode descobrir esse endereço.
Depois de aprender ASM, você perceberá que esse endereço aponta para uma instrução dentro da .textseção do executável. A .textseção é aquela que contém o código (binário) do programa a ser executado.
Você pode inspecionar isso com:
objdump -x a.out
Um exemplo prático
Conforme descrito no GCC , você pode usar isso para inicializar uma tabela de salto. Alguns geradores de scanner como o re2c (consulte o -gparâmetro) usam isso para gerar scanners mais compactos. Talvez haja até mesmo um gerador de analisador que utiliza a mesma técnica.
Respostas:
&&
é a extensão do gcc para obter o endereço do rótulo definido na função atual.void *p = &&abc
é ilegal em C99 e C ++ padrão.A compila com g ++.
fonte
void*
.__forceinline
?__declspec(naked)
? Um dos meus MSVCismos favoritos é:,template<typename T> class X { friend T; }
que é inválido C ++ 03.Como descobrir
Esse é o endereço de um rótulo e é um recurso específico do GCC .
Você poderia ter descoberto sozinho testando:
Nesse caso, o GCC diz:
Sob o capô - montagem
Você precisa conhecer o assembler para realmente entender isso, mas tentarei explicar o que significa o endereço de um rótulo.
Depois que o SO carrega o arquivo .exe do disco, um componente do sistema operacional chamado "o carregador" (o Windows tem o "PE Loader", o linux tem o "ELF loader" ou talvez até outros, se estiverem compilados no kernel), ele faz uma "virtualização" desse programa, transformando-o em um processo.
Este processo pensa que é o único na RAM e tem acesso a toda a RAM (ou seja, 0x00000000-0xFFFFFFFF em uma máquina de 32 bits).
(o texto acima é apenas uma breve visão geral do que está acontecendo, você realmente precisa aprender a montagem para entendê-lo totalmente, então tenha paciência comigo)
Agora, o rótulo em um código-fonte é basicamente um endereço. "goto label;" não faz nada mais do que um salto para aquele endereço (pense no ponteiro de instrução no assembly). Esta etiqueta armazena esse endereço de RAM e é assim que você pode descobrir esse endereço.
Depois de aprender ASM, você perceberá que esse endereço aponta para uma instrução dentro da
.text
seção do executável. A.text
seção é aquela que contém o código (binário) do programa a ser executado.Você pode inspecionar isso com:
Um exemplo prático
Conforme descrito no GCC , você pode usar isso para inicializar uma tabela de salto. Alguns geradores de scanner como o re2c (consulte o
-g
parâmetro) usam isso para gerar scanners mais compactos. Talvez haja até mesmo um gerador de analisador que utiliza a mesma técnica.fonte