Restrictions applicables aux expressions en C++ natif
Mise à jour : novembre 2007
Cette rubrique s'applique à :
Édition |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Express |
Natif uniquement |
|||
Standard |
Natif uniquement |
|||
Pro et Team |
Natif uniquement |
Légende du tableau :
Applicable |
|
Non applicable |
|
Commande ou commandes masquées par défaut. |
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.
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, 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. Le cast inverse n'est pas autorisé.
Fonctions intrinsèques et inline
Une expression de débogueur ne peut pas appeler une fonction intrinsèque ou inline sauf si cette fonction apparaît au moins une fois comme une 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.