Expressions en C++ natif
Le débogueur accepte la plupart des expressions de Microsoft et ANSI C/C++.Le débogueur fournit également des fonctions intrinsèques et des opérateurs de contexte pour rendre l'évaluation des expressions plus sécurisé et plus pratique.Cette rubrique décrit également les restrictions sur les expressions C++ qui doivent être informé de ce qui suit :
Vous ne pouvez pas utiliser l'opérateur de contexte ou la plupart des spécificateurs de format dans le code ou avec un script ou des expressions de code managé.Ils sont spécifiques à l'évaluateur d'expression en C++ natif.
Dans cette section
L'utilisation de fonctions intrinisic débogueur pour mettre à jour l'état
Utilisation d'opérateurs de contexte pour spécifier un symbole
Restrictions sur les expressions C++ natives
Contrôle d'accès
Références ambiguës
Les espaces de noms anonymes
Constructeurs, des destructeurs, et conversions
Héritage
Fonctions inline et d'intrinsèque du compilateur
Constantes numériques
Fonctions d'opérateur
Surcharge
Priorité
Formats de symbole
Cast de type
L'utilisation de fonctions intrinisic débogueur pour mettre à jour l'état
Les fonctions intrinsèques de débogueur vous offrent un moyen d'appeler certaines fonctions C/C++ dans les expressions sans modifier l'état de l'application.
Fonctions intrinsèques de débogage :
Est garanti d'être sécurisés : exécution d'une fonction intrinsèque du débogueur n'endommagera pas le processus qui est débogué.
Sont autorisés dans les expressions, même dans les cas où il n'autorise pas les effets secondaires et l'évaluation de fonction.
Fonctionnent dans les cas où les appels de fonction normale ne sont pas possibles, telles que le débogage d'un minidump.
Les fonctions intrinsèques du débogueur peuvent également rendre l'évaluation des expressions plus pratique.Par exemple, il est beaucoup plus facile à écrire strncmp(str, “asd”) dans une condition de point d'arrêt que str[0] == ‘a’ && str[1] == ‘s’ && str[2] == ‘d’.)
Zone |
Fonctions intrinsèques |
---|---|
Longueur de chaîne |
strlen, wcslen, strnlen, wcsnlen |
Comparaisons de chaînes |
strcmp, wcscmp, stricmp, _stricmp, _strcmpi, wcsicmp, _wcscmpi, _wcsnicmp, strncmp, wcsncmp, strnicmp, wcsnicmp |
La recherche de chaînes |
strchr, wcschr, strstr, wcsstr |
Win32 |
GetLastError(), TlsGetValue() |
Windows 8 |
WindowsGetStringLen(), WindowsGetStringRawBuffer() Ces fonctions requièrent que le processus qui est débogué exécuter sur windows 8.Les fichiers dump de débogage ont généré de l'windows 8 que le périphérique requiert également que l'ordinateur Visual Studio soit les fenêtres en cours de exécution 8.Toutefois, si vous déboguez un appareil windows 8 à distance, l'ordinateur Visual Studio peut exécuter Windows 7. |
Divers |
__log2 Retourne la base 2 de journal d'un entier spécifié, arrondie à l'entier inférieur le plus proche. |
Utilisation d'opérateurs de contexte pour spécifier un symbole
L'opérateur de contexte est un opérateur supplémentaire fourni par le débogueur natif.Lorsque le débogage de code natif, vous pouvez utiliser l'opérateur de contexte pour qualifier l'emplacement d'un point d'arrêt, un nom de variable, ou une expression.L'opérateur de contexte est utile pour des opérations telles que la spécification d'un nom issu d'une portée externe qui serait sinon masqué par un nom local.
Syntaxe
{,,[module] } expression
module est le nom d'un module.Vous pouvez utiliser un chemin d'accès complet pour supprimer l'ambiguïté entre les modules avec le même nom.
expression est une expression C++ valide qui le résout vers une cible valide, telle qu'un nom de fonction, un nom de variable, ou une adresse du pointeur dans module.
Les accolades doit contenir deux virgules et le nom ou le chemin d'accès complet de package (fichier exécutable ou DLL).
Par exemple, pour définir un point d'arrêt sur la fonction d' SomeFunction d'EXAMPLE.dll :
{,,EXAMPLE.dll}SomeFunction
Si le chemin d' module inclut une virgule, un espace incorporé, ou une accolade, vous devez utiliser des guillemets autour de le chemin d'accès afin que l'analyseur de contexte peut identifier correctement la chaîne.Les guillemets simples sont considérés comme faisant partie d'un nom de fichier Windows, c'est pourquoi vous devez utiliser des guillemets doubles.Par exemple :
{,"a long, long, library name.dll", } g_Var
Lorsque l'évaluateur d'expression rencontre un symbole dans une expression, il recherche le symbole en procédant dans l'ordre suivant :
Portée lexicale, vers l'extérieur, du bloc actuel (série d'instructions entre accolades) au bloc englobant.Le bloc actuel est le code contenant l'emplacement actuel (adresse du pointeur d'instruction).
Portée de la fonction.La fonction actuelle.
Portée de la classe, si l'emplacement actuel se trouve à l'intérieur d'une fonction membre C++.La portée de la classe comprend toutes les classes de base.L'évaluateur d'expression utilise les règles de dominance classiques.
Symboles globaux dans le module actuel.
Symboles publics dans le programme en cours.
Avec l'opérateur de contexte, vous spécifiez le module de départ de la recherche et passez la position actuelle.
Restrictions sur les expressions C++ natives
Lorsque vous entrez une expression C/C++ dans une fenêtre du débogueur, ces restrictions générales s'appliquent :
Contrôle d'accès
Le débogueur peut accéder à tous les membres de classe quel que soit le contrôle d'accès.Vous pouvez examiner n'importe quel membre objet de classe, y compris les classes de base et les objets membres incorporés.
Références ambiguës
Si une expression de débogueur fait référence à un nom de membre ambigu, vous devez utiliser le nom de classe pour le qualifier.Par exemple, si CObject est une instance de CClass, qui hérite des fonctions membres appelées expense de AClass et de BClass, CObject.expense est ambigu.Vous pouvez résoudre cette ambiguïté de la façon suivante :
CObject.BClass::expense
Pour résoudre les ambiguïtés, l'évaluateur d'expression applique les règles de dominance normales relatives aux noms de membres.
Les espaces de noms anonymes
L'évaluateur d'expression C++ natif ne prend pas en charge les espaces de noms anonymes.Par exemple, si vous avez le code suivant :
#include "stdafx.h"
namespace mars
{
namespace
{
int test = 0;
}
}
int main()
{
// Adding a watch on test does not work.
mars::test++;
return 0;
}
La seule façon d'observer le test de symbole dans cet exemple est d'utiliser le nom décoré :
(int*)?test@?A0xccd06570@mars@@3HA
Constructeurs, des destructeurs, et conversions
Vous ne pouvez pas appeler un constructeur ou un destructeur pour un objet, explicitement ou implicitement, en utilisant une expression qui demande la construction d'un objet temporaire.Par exemple, l'expression suivante appelle explicitement un constructeur et est à l'origine d'un message d'erreur :
Date( 2, 3, 1985 )
Vous ne pouvez pas appeler une fonction de conversion si la destination de la conversion est une classe.Une telle conversion entraîne la construction d'un objet.Par exemple, si myFraction est une instance de CFraction, qui définit l'opérateur de fonction de conversion FixedPoint, l'expression suivante génère une erreur :
(FixedPoint)myFraction
Toutefois, vous pouvez appeler une fonction de conversion si la destination de la conversion est un type intégré.Si CFraction définit une fonction de conversion operator float, l'expression suivante est valide dans le débogueur :
(float)myFraction
Vous pouvez appeler des fonctions qui retournent un objet ou déclarent des objets locaux.
Vous ne pouvez pas appeler l'opérateur new ou delete.L'expression suivante ne fonctionne pas dans le débogueur :
new Date(2,3,1985)
Héritage
Lorsque vous utilisez le débogueur pour afficher un objet de classe qui a des classes de base virtuelles, les membres de la classe de base virtuelle sont affichés pour chaque chemin d'héritage, même si une seule instance de ces membres est stockée.
Les appels de fonctions virtuelles sont correctement gérés par l'évaluateur d'expression.Par exemple, supposons que la classe CEmployee définisse la fonction virtuelle computePay, qui est redéfinie dans une classe héritant de CEmployee.Vous pouvez appeler computePay via un pointeur dirigé vers CEmployee et ainsi faire s'exécuter la fonction appropriée :
empPtr->computePay()
Vous pouvez effectuer un cast d'un pointeur vers un objet de classe dérivée en un pointeur vers un objet de classe de base.Vous pouvez effectuer un cast d'un pointeur vers un objet de classe de base en un pointeur vers un objet de classe dérivée, sauf lorsque l'héritage est virtuel.
Fonctions inline et d'intrinsèque du compilateur
Une expression du débogueur ne peut pas appeler des fonctions intrinsèques du compilateur ou la fonction inline à moins que la fonction s'affiche au moins une fois comme fonction normale.
Constantes numériques
Les expressions du débogueur peuvent utiliser des constantes entières au format octal, hexadécimal ou décimal.Par défaut, le débogueur attend des constantes décimales.Ce paramètre peut être modifié sur la page Général de l'onglet Débogage.
Vous pouvez utiliser des symboles de préfixe ou de suffixe pour représenter les nombres dans une autre base.Le tableau suivant affiche les formes que vous pouvez utiliser.
Syntaxe |
Exemple (décimal 100) |
Base |
---|---|---|
chiffres |
100 ou 64 ; |
Décimal ou hexadécimal, selon le paramètre actuel. |
0chiffres |
0144 |
Octale (base 8) |
0nchiffres |
0n100 |
Décimale (base 10) |
0xchiffres |
0x64 |
Hexadécimale (base 16) |
chiffresh |
64h |
Hexadécimale (base 16) |
Fonctions d'opérateur
Une expression de débogueur peut appeler des fonctions d'opérateur pour une classe implicitement ou explicitement.Par exemple, supposons que myFraction et yourFraction soient des instances d'une classe qui définit operator+.Vous pouvez afficher la somme de ces deux objets en utilisant cette expression :
myFraction + yourFraction
Si une fonction d'opérateur est définie comme une fonction amie, vous pouvez l'appeler implicitement en utilisant la même syntaxe que pour la fonction membre ou explicitement en utilisant la syntaxe suivante :
operator+( myFraction, yourFraction )
Comme les fonctions ordinaires, les fonctions d'opérateur ne peuvent pas être appelées à l'aide d'arguments qui requièrent une conversion impliquant la construction d'objet.
Le débogueur ne prend pas en charge les opérateurs surchargés avec des versions à la fois const et non const.Les opérateurs surchargés avec des versions const et non-const sont utilisés fréquemment dans la bibliothèque de modèles standard.
Surcharge
Une expression de débogueur peut appeler des fonctions surchargées si une correspondance exacte existe ou si une correspondance ne requiert pas une conversion impliquant la construction d'un objet.Par exemple, si la fonction calc utilise un objet CFraction comme paramètre et que la classe CFraction définit un constructeur à argument unique admettant un entier, l'expression suivante génère une erreur :
calc( 23 )
Même s'il existe une conversion valide permettant de convertir l'entier en l'objet CFraction attendu par calc, une telle conversion implique la création d'un objet et n'est pas prise en charge.
Priorité
Dans les expressions du débogueur, l'opérateur de portée C++ (::) a une priorité moins élevée que dans le code source.Dans le code source C++, il a la priorité la plus élevée.Dans le débogueur, il est prioritaire sur les opérateurs de base et de suffixe (->, ++, --) et les opérateurs unaires (!, &, * et autres).
Formats de symbole
Vous pouvez entrer une expression de débogueur qui contient des symboles sous la même forme que celle utilisée dans le code source, à condition que les symboles se trouvent dans un module compilé avec des informations de débogage complètes (/Zi ou /ZI).Si vous entrez une expression qui contient des symboles publics, qui sont les symboles contenus dans les bibliothèques ou dans les modules compilés avec /Zd, vous devez utiliser le nom décoré du symbole (la forme utilisée dans le code objet).Pour plus d'informations, consultez /Z7, /Zd, /Zi, /ZI (Format des informations de débogage).
Vous pouvez obtenir une liste de tous les noms dans leurs formes décorées et non décorées en utilisant l'option LINK /MAP.Pour plus d'informations, consultez /MAP (générer fichier de mappage).
La décoration de nom est le mécanisme utilisé pour appliquer des liaisons de type sécurisé.Cela signifie que seuls les noms et les références ayant une orthographe, une casse, une convention d'appel et un type correspondant précisément à une décoration sont liés.
Le premier caractère des noms déclarés avec la convention d'appel C (implicitement ou explicitement à l'aide du mot clé _cdecl) est un caractère de soulignement (_).Par exemple, la fonction main peut être affichée sous la forme _main.Les noms déclarés sous la forme _fastcall commencent par le symbole @.
Pour C++, le nom décoré encode le type du symbole, en plus de la convention d'appel.Cette forme du nom peut être longue et difficile à lire.Le nom commence par au moins un point d'interrogation (?).Pour les fonctions C++, la décoration contient la portée de la fonction, les types de paramètres de fonctions et le type de retour de la fonction.
Cast de type
Si vous effectuez un cast dans un type spécifique, ce type doit être connu du débogueur.Un autre objet de ce type doit exister dans votre programme.Les types créés en utilisant les instructions typedef ne sont pas pris en charge.