Nomes decorados

Funções, dados e objetos em programas C e C++ são representados internamente por seus nomes decorados. Um nome decorado é uma cadeia de caracteres codificada criada pelo compilador durante a compilação de uma definição de função, objeto ou dados. Ele registra convenções de chamada, tipos, parâmetros de função e outras informações junto com o nome. Essa decoração de nome, também conhecida como mangling de nome, ajuda o vinculador a encontrar as funções e os objetos corretos ao vincular um executável.

As convenções de nomenclatura com decoração foram alteradas em várias versões do Visual Studio e também podem ser diferentes em arquiteturas de destino diferentes. Para vincular corretamente com arquivos de origem criados usando o Visual Studio, as DLLs e bibliotecas de C e C++ devem ser compilados usando o mesmo conjunto de ferramentas, sinalizadores e arquitetura de destino do compilador.

Observação

Bibliotecas criadas pelo Visual Studio 2015 ou posterior podem ser consumidas por aplicativos criados com versões posteriores do Visual Studio por meio do Visual Studio 2022. Para obter mais informações, consulte Compatibilidade binária do C++ entre versões do Visual Studio.

Usando nomes decorados

Normalmente, você não precisa saber o nome decorado para escrever código que compila e vincula com êxito. Os nomes decorados são um detalhe de implementação interno ao compilador e ao vinculador. As ferramentas geralmente podem manipular o nome em seu formato não decorado. No entanto, às vezes um nome decorado é necessário quando você especifica um nome de função para o vinculador e outras ferramentas. Por exemplo, para corresponder funções de C++ sobrecarregadas, membros de namespaces, construtores de classe, destruidores e funções membro especiais, você precisa especificar o nome decorado. Para obter detalhes sobre os sinalizadores de opção e outras situações que exigem nomes decorados, consulte a documentação das ferramentas e opções que você está usando.

Se você alterar o nome da função, a classe, a convenção de chamada, o tipo de retorno ou qualquer parâmetro, o nome decorado também será alterado. Nesse caso, você precisará obter o novo nome decorado e usá-lo em todos os lugares em que o nome decorado for especificado.

A decoração de nome também é importante ao vincular ao código escrito em outras linguagens de programação ou ao usar outros compiladores. Compiladores diferentes usam convenções de decoração de nome diferentes. Quando seu executável vincular a código escrito em outra linguagem, será necessário tomar cuidado especial para fazer a correspondência entre os nomes exportados e importados e as convenções de chamada. O código de linguagem do assembly deve usar os nomes decorados do MSVC e as convenções de chamada para vincular ao código-fonte escrito usando MSVC.

Formato de um nome decorado do C++

Um nome decorado para uma função de C++ contém as seguintes informações:

  • O nome da função.

  • A classe da qual a função é membro, se for uma função membro. A decoração pode incluir a classe que inclui a classe que contém a função e assim por diante.

  • O namespace ao qual a função pertence, se faz parte de um namespace.

  • Os tipos dos parâmetros de função.

  • A convenção de chamada.

  • O tipo de retorno da função.

  • Um elemento opcional específico do destino. Em objetos ARM64EC, uma marca $$h é inserida no nome.

Os nomes de função e classe são codificados no nome decorado. O restante do nome decorado é um código que tem significado interno apenas para o compilador e o vinculador. Veja a seguir exemplos de nomes decorados e não decorados de C++.

Nome não decorado Nome decorado
int a(char){int i=3;return i;}; ?a@@YAHD@Z
void __stdcall b::c(float){}; ?c@b@@AAGXM@Z

Formato de um nome decorado de C

A forma de decoração de uma função de C depende da convenção de chamada usada em sua declaração, conforme mostrado na tabela a seguir. É também o formato de decoração usado quando o código C++ é declarado com vinculação extern "C". A convenção de chamada padrão é __cdecl. Em um ambiente de 64 bits, funções de extern "C" ou C só são decoradas ao usar a convenção de chamada __vectorcall.

Convenção de chamada Decoração
__cdecl Sublinhado à esquerda (_)
__stdcall Sublinhado à esquerda (_) e um espaço à direita no sinal (@) seguido pelo número de bytes na lista de parâmetros, em decimal
__fastcall Espaço à esquerda e à direita nos sinais (@), seguido por um número decimal que representa o número de bytes na lista de parâmetros
__vectorcall Dois espaços à direita nos sinais (@@) seguidos por um número decimal de bytes na lista de parâmetros

Para funções do ARM64EC com vinculação C (sejam elas compiladas como C ou usando extern "C"), um # é pré-acrescentado ao nome decorado.

Exibir nomes decorados

Você pode obter a forma decorada de um nome de símbolo depois de compilar o arquivo de origem que contém o protótipo ou a definição de função, dados ou objeto. Para examinar nomes decorados em seu programa, você pode usar um dos seguintes métodos:

Para usar uma listagem para exibir nomes decorados

  1. Gere uma listagem compilando o arquivo de origem que contém o protótipo ou a definição de função, dados ou objeto com a opção do compilador /FA (tipo de arquivo de listagem) definida como assembly com código-fonte (/FAs).

    Por exemplo, insira cl /c /FAs example.cpp em um prompt de comando do desenvolvedor para gerar um arquivo de listagem, example.asm.

  2. No arquivo de listagem resultante, localize a linha que começa com PUBLIC e termina um ponto e vírgula (;), seguido pelos dados não decorados ou pelo nome da função. O símbolo entre PUBLIC e o ponto e vírgula é o nome decorado.

Para usar DUMPBIN para exibir nomes decorados

  1. Para ver os símbolos exportados em um arquivo OBJ ou LIB, insira dumpbin /exports <obj-or-lib-file> em um prompt de comando do desenvolvedor.

  2. Para encontrar a forma decorada de um símbolo, procure o nome não decorado entre parênteses. O nome decorado está na mesma linha, antes do nome não decorado.

Exibindo nomes não decorados

Você pode usar undname.exe para converter um nome decorado em sua forma não decorada. Este exemplo mostra como funciona:

C:\>undname ?func1@a@@AAEXH@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?func1@a@@AAEXH@Z"
is :- "private: void __thiscall a::func1(int)"

Confira também

Ferramentas de compilação adicionais MSVC
Usando extern para especificar a vinculação