Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Aggiornamento: novembre 2007
Le informazioni contenute in questo argomento sono valide per:
Edition |
Visual Basic |
C# |
C++ |
Web Developer |
|---|---|---|---|---|
Express |
![]() |
![]() |
Solo nativo |
![]() |
Standard |
![]() |
![]() |
Solo nativo |
![]() |
Pro e Team |
![]() |
![]() |
Solo nativo |
![]() |
Legenda tabella:
![]() |
Si applica |
![]() |
Non applicabile |
![]() |
Comando o comandi nascosti per impostazione predefinita. |
Quando si immette un'espressione C/C++ in una finestra del debugger, vengono applicate le seguenti restrizioni generali:
Controllo di accesso
Il debugger può accedere a tutti i membri di classe indipendentemente dal controllo di accesso. È possibile esaminare qualsiasi membro di un oggetto classe, inclusi gli oggetti membro incorporati e le classi base.
Riferimenti ambigui
Se un'espressione del debugger fa riferimento a un nome di membro ambiguo, è necessario utilizzare il nome della classe per qualificarlo. Se ad esempio CObject è un'istanza di CClass, che eredita le funzioni membro denominate expense da AClass e BClass, CObject.expense risulterà ambiguo. È possibile risolvere tale ambiguità come segue:
CObject.BClass::expense
Per risolvere le ambiguità, l'analizzatore di espressioni applica le normali regole di dominanza relative ai nomi di membro.
Spazi dei nomi anonimi
L'analizzatore di espressioni in linguaggio C++ nativo non supporta gli spazi dei nomi anonimi. Si supponga, ad esempio, che esista il seguente codice:
#include "stdafx.h"
namespace mars
{
namespace
{
int test = 0;
}
}
int main()
{
// Adding a watch on test does not work.
mars::test++;
return 0;
}
L'unico modo per controllare il simbolo test in questo esempio consiste nell'utilizzare il nome decorato:
(int*)?test@?A0xccd06570@mars@@3HA
Costruttori, distruttori e conversioni
Non è possibile chiamare in modo implicito o esplicito un costruttore o un distruttore relativo a un oggetto, utilizzando un'espressione che richiede la costruzione di un oggetto temporaneo. La seguente espressione, ad esempio, chiama in modo esplicito un costruttore generando in questo modo un messaggio di errore:
Date( 2, 3, 1985 )
Se la destinazione della conversione è una classe, non sarà possibile chiamare una funzione di conversione. Tale conversione comporta la costruzione di un oggetto. Se, ad esempio, myFraction è un'istanza di CFraction che definisce l'operatore della funzione di conversione FixedPoint, la seguente espressione genererà un errore:
(FixedPoint)myFraction
Se la destinazione della conversione è un tipo incorporato, sarà tuttavia possibile chiamare una funzione di conversione. Se CFraction definisce una funzione di conversione operator float, la seguente espressione verrà considerata valida nel debugger:
(float)myFraction
È possibile chiamare le funzioni che restituiscono un oggetto o dichiarano oggetti locali.
Non è invece possibile chiamare gli operatori new e delete. La seguente espressione non funziona nel debugger:
new Date(2,3,1985)
Ereditarietà
Quando si utilizza il debugger per visualizzare un oggetto classe che include classi base virtuali, i membri della classe base virtuale vengono visualizzati per ciascun percorso di ereditarietà, anche se ne viene memorizzata una sola istanza.
Le chiamate di funzioni virtuali vengono gestite in modo corretto nell'analizzatore di espressioni. Si supponga, ad esempio, che la classe CEmployee definisca la funzione virtuale computePay ridefinita in una classe che eredita da CEmployee. È possibile chiamare computePay tramite un puntatore a CEmployee e fare in modo che venga eseguita la funzione appropriata:
empPtr->computePay()
È possibile eseguire il cast di un puntatore a un oggetto classe derivata in un puntatore a un oggetto classe base. Il cast inverso non è invece consentito.
Funzioni intrinseche e inline
Le espressioni del debugger non possono chiamare una funzione intrinseca o inline, a meno che tale funzione non appaia almeno una volta come funzione normale.
Costanti numeriche
Le espressioni del debugger possono utilizzare le costanti integer nel formato ottale, esadecimale o decimale. Per impostazione predefinita, nel debugger le costanti vengono assunte come espresse in decimale. Questa impostazione può essere modificata nella pagina Generale della scheda Debug.
Per rappresentare i numeri in un'altra base, è possibile utilizzare i simboli di prefisso o di suffisso. Nella tabella riportata di seguito sono elencati i formati utilizzabili.
Sintassi |
Esempio (decimale 100) |
Base |
|---|---|---|
cifre |
100 o 64 |
Decimale o esadecimale in base all'impostazione corrente |
0cifre |
0144 |
Ottale (base 8) |
0ncifre |
0n100 |
Decimale (base 10) |
0xcifre |
0x64 |
Esadecimale (base 16) |
cifreh |
64h |
Esadecimale (base 16) |
Funzioni degli operatori
Un'espressione del debugger può richiamare in modo implicito o esplicito le funzioni degli operatori relative a una classe. Si supponga, ad esempio, che myFraction e yourFraction siano istanze di una classe che definisce operator+. È possibile visualizzare la somma di questi due oggetti utilizzando la seguente espressione:
myFraction + yourFraction
Se la funzione di un operatore è definita come friend, è possibile chiamarla in modo implicito mediante la stessa sintassi utilizzata per una funzione membro oppure richiamarla in modo esplicito nel seguente modo:
operator+( myFraction, yourFraction )
Analogamente alle funzioni ordinarie, non è possibile chiamare le funzioni degli operatori con argomenti che richiedono una conversione che comporta la costruzione di un oggetto.
Nel debugger non sono supportati operatori di overload con entrambe le versioni const e non const. Tali operatori vengono spesso utilizzati nella Libreria di modelli standard.
Overload
Un'espressione del debugger può chiamare le funzioni in overload se esiste una corrispondenza esatta o se per una corrispondenza non è richiesta una conversione che comporti la costruzione di un oggetto. Se, ad esempio, la funzione calc accetta un oggetto CFraction come parametro e la classe CFraction definisce un costruttore con un singolo argomento che accetta un valore integer, la seguente espressione genererà un errore:
calc( 23 )
Anche se è disponibile una conversione valida per convertire i valori integer nell'oggetto CFraction previsto da calc, questo tipo di conversione comporta la creazione di un oggetto e pertanto non è supportato.
Precedenza
Nelle espressioni del debugger l'operatore di ambito C++ (::) ha una precedenza più bassa rispetto a quando si trova nel codice sorgente. Nel codice sorgente C++ tale operatore ha la precedenza più alta. Nel debugger la precedenza rientra tra gli operatori base e suffissi (->, ++, --) e gli operatori unari (!, &, * e altri).
Formati di simbolo
È possibile immettere un'espressione del debugger contenente dei simboli nello stesso formato utilizzato nel codice sorgente, a condizione che tali simboli si trovino in un modulo compilato con informazioni di debug complete (/Zi o /ZI). Se viene immessa un'espressione contenente simboli pubblici, ovvero simboli disponibili nelle librerie o nei moduli compilati con /Zd, è necessario utilizzare il nome decorato del simbolo, ossia il formato utilizzato nel codice oggetto. Per ulteriori informazioni, vedere /Z7, /Zd, /Zi, /ZI (Formato informazioni di debug).
Specificando l'opzione di LINK /MAP, è possibile ottenere un elenco di tutti i nomi nei formati decorati e non decorati. Per ulteriori informazioni, vedere /MAP (Genera file Map).
La decorazione dei nomi è un meccanismo utilizzato per attivare il collegamento indipendente dai tipi. Questo significa che vengono collegati solo i nomi e i riferimenti con ortografia, maiuscole/minuscole, convenzione di chiamata e tipo perfettamente corrispondenti.
I nomi dichiarati con la convenzione di chiamata C, in modo implicito o esplicito mediante la parola chiave _cdecl, iniziano con un carattere di sottolineatura (_). La funzione main può ad esempio essere visualizzata come _main. I nomi dichiarati come _fastcall iniziano con il simbolo @.
Per il linguaggio C++, il nome decorato codifica il tipo del simbolo oltre alla convenzione di chiamata. Questo formato di nome può risultare lungo e di difficile lettura. Il nome inizia con almeno un punto interrogativo (?). Per le funzioni C++, la decorazione include l'ambito della funzione, i tipi dei parametri della funzione e il tipo restituito della funzione.
Cast di tipo
Se si esegue il cast a un tipo, è necessario che questo venga riconosciuto dal debugger. Nel programma deve essere presente un altro oggetto dello stesso tipo. I tipi creati mediante istruzioni typedef non sono supportati.
.gif)
.gif)
.gif)