Nomi decorati

Le funzioni, i dati e gli oggetti nei programmi C e C++ sono rappresentati internamente dai nomi decorati. Un nome decorato è una stringa codificata creata dal compilatore durante la compilazione di un oggetto, di dati o di una definizione di funzione. Registra convenzioni di chiamata, tipi, parametri di funzione e altre informazioni insieme al nome. Questa decorazione del nome, nota anche come mangling dei nomi, consente al linker di trovare le funzioni e gli oggetti corretti durante il collegamento di un eseguibile.

Le convenzioni di denominazione decorate sono state modificate in diverse versioni di Visual Studio e possono anche essere diverse in architetture di destinazione diverse. Per collegare correttamente i file di origine creati tramite Visual Studio, DLL e DLL C++ e librerie devono essere compilati usando lo stesso set di strumenti, flag e architettura di destinazione del compilatore.

Nota

Le librerie create da Visual Studio 2015 o versioni successive possono essere utilizzate dalle applicazioni compilate con versioni successive di Visual Studio tramite Visual Studio 2022. Per altre informazioni, vedere Compatibilità binaria C++ tra le versioni di Visual Studio.

Uso di nomi decorati

Di solito non è necessario conoscere il nome decorato per scrivere un codice che esegua la compilazione e crei il collegamento correttamente. I nomi decorati sono un dettaglio di implementazione interno del compilatore e del linker. Gli strumenti in genere possono gestire il nome nel formato non decorato. Tuttavia, un nome decorato a volte è necessario quando si specifica un nome di funzione per il linker e altri strumenti. Ad esempio, per trovare una corrispondenza con funzioni C++ in overload, membri di spezi dei nomi, costruttori di classe, distruttori e speciali funzioni membro, è necessario specificare il nome decorato. Per informazioni dettagliate sui flag di opzione e altre situazioni che richiedono nomi decorati, vedere la documentazione relativa agli strumenti e alle opzioni in uso.

Se si modifica il nome della funzione, la classe, la convenzione di chiamata, il tipo restituito o qualsiasi parametro, viene modificato anche il nome decorato. In questo caso, è necessario ottenere il nuovo nome decorato e usarlo ovunque sia specificato il nome decorato.

La decorazione dei nomi è importante anche quando si crea un collegamento a un codice scritto in altri linguaggi di programmazione o si usano altri compilatori. Ogni compilatore usa una convenzione di decorazione dei nomi diversa. Quando l'eseguibile crea un collegamento a un codice scritto in un altro linguaggio, si deve prestare particolare attenzione nel trovare una corrispondenza con i nomi esportati e importati e con le convenzioni di chiamata. Il codice del linguaggio assembly deve usare i nomi decorati MSVC e le convenzioni di chiamata per il collegamento al codice sorgente scritto tramite MSVC.

Formato di un nome decorato C++

Un nome decorato per una funzione C++ contiene le informazioni seguenti:

  • Nome della funzione.

  • Classe di cui la funzione è membro, se si tratta di una funzione membro. La decorazione può includere la classe che racchiude la classe che contiene la funzione e così via.

  • Lo spazio dei nomi a cui appartiene la funzione, se fa parte di uno spazio dei nomi.

  • Tipi dei parametri della funzione.

  • Convenzione di chiamata.

  • Tipo restituito della funzione.

  • Elemento facoltativo specifico della destinazione. Negli oggetti ARM64EC viene inserito un $$h tag nel nome.

I nomi della funzione e della classe vengono codificati nel nome decorato. La parte rimanente del nome decorato è un codice con un significato interno solo per il compilatore e il linker. Di seguito sono riportati esempi di nomi di C++ non decorati e decorati.

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

Formato di un nome decorato C

Il formato della decorazione per una funzione C dipende dalla convenzione di chiamata usata nella dichiarazione, come mostrato nella tabella seguente. È anche il formato di decorazione usato quando il codice C++ viene dichiarato in modo da avere extern "C" un collegamento. La convenzione di chiamata predefinita è __cdecl. In un ambiente a 64 bit, le funzioni o extern "C" C vengono decorate solo quando si usa la convenzione di __vectorcall chiamata.

Convenzione di chiamata Decorazione
__cdecl Carattere di sottolineatura iniziale (_)
__stdcall Carattere di sottolineatura iniziale (_) e un segno finale (@) seguito dal numero di byte nell'elenco dei parametri in decimale
__fastcall Segno iniziale e finale (@) seguito da un numero decimale che rappresenta il numero di byte nell'elenco dei parametri
__vectorcall Due segni finali (@@) seguiti da un numero decimale di byte nell'elenco dei parametri

Per ARM64EC funzioni con collegamento C (compilato come C o tramite extern "C"), un # oggetto viene anteporto al nome decorato.

Visualizzare i nomi decorati

È possibile ottenere il formato decorato di un nome di simbolo dopo avere compilato il file di origine contenente il prototipo o la definizione di dati, oggetti o funzioni. Per esaminare i nomi decorati nel programma, è possibile usare uno dei metodi seguenti:

Per usare un listato per la visualizzazione dei nomi decorati

  1. Generare un elenco compilando il file di origine che contiene i dati, l'oggetto o la definizione di funzione o il prototipo con l'opzione del /FA compilatore (List file type) impostata su assembly con codice sorgente (/FAs).

    Ad esempio, immettere cl /c /FAs example.cpp al prompt dei comandi per gli sviluppatori per generare un file di presentazione, example.asm.

  2. Nel file di elenco risultante trovare la riga che inizia con PUBLIC e termina un punto e virgola (;) seguito dai dati non decorati o dal nome della funzione. Il simbolo tra PUBLIC e il punto e virgola è il nome decorato.

Per usare DUMPBIN per la visualizzazione dei nomi decorati

  1. Per visualizzare i simboli esportati in un file OBJ o LIB, immettere dumpbin /exports <obj-or-lib-file> al prompt dei comandi per gli sviluppatori.

  2. Per trovare il formato decorato di un simbolo, cercare il nome non decorato tra parentesi. Il nome decorato si trova nella stessa riga, prima del nome non dichiarato.

Visualizzazione di nomi nondecorati

È possibile usare undname.exe per convertire un nome decorato nel formato non decorato. In questo esempio viene illustrato come funziona:

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)"

Vedi anche

Strumenti di compilazione aggiuntivi MSVC
Uso extern di per specificare il collegamento