Restrizioni relative alle espressioni in linguaggio C++ nativo

Aggiornamento: novembre 2007

Le informazioni contenute in questo argomento sono valide per:

Edition

Visual Basic

C#

C++

Web Developer

Express

Argomento non applicabile Argomento non applicabile

Solo nativo

Argomento non applicabile

Standard

Argomento non applicabile Argomento non applicabile

Solo nativo

Argomento non applicabile

Pro e Team

Argomento non applicabile Argomento non applicabile

Solo nativo

Argomento non applicabile

Legenda tabella:

Argomento applicabile

Si applica

Argomento non applicabile

Non applicabile

Argomento valido ma comando nascosto per impostazione predefinita

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.

Vedere anche

Altre risorse

Espressioni in linguaggio C++ nativo