Expressions dans le débogueur Visual Studio

Le débogueur Visual Studio inclut des évaluateurs d’expression qui fonctionnent lorsque vous entrez une expression dans la boîte de dialogue Espion express , la fenêtre Espion ou la fenêtre Exécution . Les évaluateurs d’expression travaillent également dans la fenêtre Points d’arrêt et à beaucoup d’autres emplacements du débogueur.

Les sections suivantes décrivent les limitations de l’évaluation des expressions pour les langages pris en charge par Visual Studio.

Les expressions F# ne sont pas prises en charge

Les expressions F# ne sont pas reconnues. Si vous déboguez du code F#, vous devez traduire vos expressions en syntaxe C# avant d’introduire les expressions dans une boîte de dialogue ou fenêtre de débogueur. Quand vous traduisez des expressions de F# en C#, gardez à l’esprit que C# utilise l’opérateur == pour tester l’égalité, tandis que F# utilise un seul =.

Expressions en C++

Pour plus d’informations sur l’utilisation des opérateurs de contexte avec des expressions en C++, consultez Context Operator (C++).

Expressions non prises en charge en C++

Constructeurs, destructeurs et conversions

Vous ne pouvez pas appeler un constructeur ni un destructeur pour un objet, explicitement ou implicitement. Par exemple, l’expression suivante appelle explicitement un constructeur et est à l’origine d’un message d’erreur :

my_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

Vous ne pouvez pas appeler l’opérateur new ou delete. Par exemple, l’expression suivante n’est pas prise en charge :

new Date(2,3,1985)

Macros de préprocesseur

Les macros de préprocesseur ne sont pas prises en charge dans le débogueur. Par exemple, si une constante VALUE est déclarée comme : #define VALUE 3, vous ne pouvez pas utiliser VALUE dans la fenêtre Espion. Pour éviter cette limitation, vous devez remplacer les éléments #definepar des énumérations et des fonctions chaque fois que possible.

Déclarations d’espaces de noms using

Vous ne pouvez pas utiliser de déclarations using namespace . Pour accéder à un nom de type ou une variable en dehors de l’espace de noms actuel, vous devez utiliser le nom qualifié complet.

Espaces de noms anonymes

Les espaces de noms anonymes ne sont pas pris en charge. Si vous avez le code suivant, vous ne pouvez pas ajouter test à la fenêtre Espion :

namespace mars
{
    namespace
    {
        int test = 0;
    }
}
int main()
{
    // Adding a watch on test doesn't work.
    mars::test++;
    return 0;
}

Utilisation de fonctions intrinsèques du débogueur pour maintenir l’état

Les fonctions intrinsèques du débogueur vous permettent d’appeler certaines fonctions C/C++ dans les expressions sans modifier l’état de l’application.

Fonctions intrinsèques du débogueur :

  • Garanties comme sécurisées : l’exécution d’une fonction intrinsèque du débogueur n’endommagera pas le processus qui est en cours de débogage.

  • Autorisées dans toutes les expressions, même dans les scénarios où les effets secondaires et l’évaluation de fonction ne sont pas autorisés.

  • Fonctionnent dans les scénarios où les appels de fonction normaux sont impossibles, tels 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 d’écrire strncmp(str, "asd") dans une condition de point d’arrêt que str[0] == 'a' && str[1] == 's' && str[2] == 'd'. )

Domaine Fonctions intrinsèques
Longueur de la chaîne strlen, wcslen, strnlen, wcsnlen
Comparaison de chaînes strcmp, wcscmp, stricmp, wcsicmp, _stricmp, _strcmpi, _wcsicmp, _wcscmpi, strncmp, wcsncmp, strnicmp, wcsnicmp, _strnicmp, _wcsnicmp
Recherche de chaîne strchr, wcschr, memchr, wmemchr, strstr, wcsstr
Win32 CoDecodeProxy, DecodePointer, GetLastError, TlsGetValue
Windows 8 RoInspectCapturedStackBackTrace, WindowsCompareStringOrdinal, WindowsGetStringLen, WindowsGetStringRawBuffer

Ces fonctions requièrent que le processus en cours de débogage s’exécute sur Windows 8. Le débogage des fichiers dump générés à partir d’un appareil Windows 8 requiert également que l’ordinateur Visual Studio exécute Windows 8. Toutefois, si vous déboguez un appareil Windows 8 à distance, l’ordinateur Visual Studio peut exécuter Windows 7.
WindowsGetStringLen et WindowsGetStringRawBuffer sont utilisés uniquement par le moteur d’exécution (EE) au niveau source.
Divers __log2 : retourne le logarithme base 2 d’un entier spécifié, arrondi à l’entier inférieur le plus proche.

__findNonNull : recherche un tableau de pointeurs et renvoie l’indice du premier élément non null.
– Paramètres : (1) Pointeur vers le premier élément du tableau (void*), (2) Taille du tableau (int non signé).
– Valeurs de retour : (1) indice de base 0 du premier élément non null dans le tableau ou –1 s’il est introuvable.

DecodeHString : fonction d’assistance pour mettre en forme la valeur d’un HSTRING. Extrait la valeur HSTRING de la pile, envoie (push) les octets d’une structure StringInfo que le moteur d’exécution peut utiliser pour indiquer l’emplacement de la chaîne. Ce n’est utilisé qu’en interne par le moteur d’exécution. Ce n’est pas disponible pour être appelé directement par l’utilisateur.

DecodeWinRTRestrictedException : décode une exception restreinte WinRT pour obtenir la description restreinte.
– Paramètres : (1) caractères d’une chaîne terminée par null représentant la chaîne de référence restreinte.
– Valeur de retour : caractères d’une chaîne terminée par null contenant le message d’erreur réel à afficher.

DynamicCast : implémente dynamic_cast.
– Paramètres : (1) pointeur vers l’objet à caster.
– Éléments de données : un objet CDynamicCastData doit être associé en tant qu’élément de données à l’instruction ExecuteIntrinsic() correspondante. L’élément de données encode le type duquel et vers lequel le cast est effectué, ainsi que si nous évaluons ou non une expression natvis (nécessaire pour que les diagnostics interrompent la récursivité infinie).
– Valeur de retour : (1) pointeur vers l’objet, cast vers le type correct ou NULL si l’objet casté n’est pas une instance du type correct.

DynamicMemberLookup : fonction d’assistance pour obtenir dynamiquement la valeur d’un membre de classe

GetEnvBlockLength : fonction d’assistance pour obtenir la longueur d’un bloc d’environnement, en caractères. Utilisé pour $env.

Stdext_HashMap_Int_OperatorBracket_idx : operator[] pour stdext::hash_map. Suppose la fonction de hachage par défaut avec une clé « int ». Retourne la valeur. L’opérateur intrinsèque operator[] prend uniquement en charge la récupération d’éléments existants à partir de la table de hachage. Il ne prend pas en charge l’insertion de nouveaux éléments dans la table, car cela peut impliquer une complexité indésirable, telle que l’allocation de mémoire. Toutefois, operator[] peut être utilisé pour modifier la valeur associée à une clé figurant déjà dans la table.
– Paramètres de pile : (1) adresse de l’objet stdext::hash_map, (2) clé dans la table (int), (3) structure HashMapPdb qui spécifie les décalages de champ des membres dont l’implémentation de la fonction a besoin pour effectuer la recherche. Cela est obligatoire, car l’accès direct aux symboles n’est pas disponible du côté distant.
– Valeurs de retour : (1) si la clé se trouve dans la table, l’adresse de la valeur qui correspond à la clé. Sinon, NULL.

Std_UnorderedMap_Int_OperatorBracket_idx : std::unordered_map fonctionne de la même façon que stdext::hash_map, si ce n’est que la fonction de hachage est différente.

ConcurrencyArray_OperatorBracket_idx // Concurrency::array<>::operator[index<>] et operator(index<>)

ConcurrencyArray_OperatorBracket_int // Concurrency::array<>::operator(int, int, ...)

ConcurrencyArray_OperatorBracket_tidx // Concurrency::array<>::operator[tiled_index<>] et operator(tiled_index<>)

ConcurrencyArrayView_OperatorBracket_idx // Concurrency::array_view<>::operator[index<>] et operator(index<>)

ConcurrencyArrayView_OperatorBracket_int // Concurrency::array_view<>::operator(int, int, ...)

ConcurrencyArrayView_OperatorBracket_tidx // Concurrency::array_view<>::operator[tiled_index<>] et operator(tiled_index<>)

TreeTraverse_Init : initialise un nouveau parcours d’arborescence.
Prend en charge les visualiseurs basés sur l’extension, non destinés à être utilisés dans les fichiers .natvis.

TreeTraverse_Next : récupère les nœuds d’un parcours d’arborescence en attente.
Prend en charge les visualiseurs basés sur l’extension, non destinés à être utilisés dans les fichiers .natvis.

TreeTraverse_Skip : ignore les nœuds d’un parcours d’arborescence en attente.
Prend en charge les visualiseurs basés sur l’extension, non destinés à être utilisés dans les fichiers .natvis.

Expressions non prises en charge en C++/CLI

  • Les casts qui utilisent des pointeurs, ou casts définis par l’utilisateur, ne sont pas pris en charge.

  • La comparaison et l’assignation d’objet ne sont pas prises en charge.

  • Les opérateurs surchargés et les fonctions surchargées ne sont pas pris en charge.

  • La conversion boxing et unboxing n’est pas prise en charge.

  • L’opérateur Sizeof n’est pas pris en charge.

Expressions non prises en charge en C#

Objets dynamiques

Vous pouvez utiliser des variables dans les expressions du débogueur qui sont typées statiquement comme dynamiques. Quand des objets qui implémentent IDynamicMetaObjectProvider sont évalués dans la fenêtre Espion, un nœud Affichage dynamique est ajouté. Le nœud Affichage dynamique affiche les membres de l’objet, mais n’autorise pas la modification des valeurs des membres.

Les fonctionnalités suivantes des objets dynamiques ne sont pas prises en charge :

  • Opérateurs composés +=, -=, %=, /=et *=

  • De nombreux casts, notamment les casts numériques et casts d’argument de type

  • Appels de méthode avec plus de deux arguments

  • Accesseurs Get de propriété comportant plus de deux arguments

  • Accesseurs Set de propriété comportant des arguments

  • Assignation à un indexeur

  • Opérateurs booléens && et ||

Méthodes anonymes

La création de méthodes anonymes n’est pas prise en charge.

Expressions non prises en charge en Visual Basic

Objets dynamiques

Vous pouvez utiliser des variables dans les expressions du débogueur qui sont typées statiquement comme dynamiques. Quand des objets qui implémentent l’interface IDynamicMetaObjectProvider sont évalués dans la fenêtre Espion, un nœud Affichage dynamique est ajouté. Le nœud Affichage dynamique affiche les membres de l’objet, mais n’autorise pas la modification des valeurs des membres.

Les fonctionnalités suivantes des objets dynamiques ne sont pas prises en charge :

  • Opérateurs composés +=, -=, %=, /=et *=

  • De nombreux casts, notamment les casts numériques et casts d’argument de type

  • Appels de méthode avec plus de deux arguments

  • Accesseurs Get de propriété comportant plus de deux arguments

  • Accesseurs Set de propriété comportant des arguments

  • Assignation à un indexeur

  • Opérateurs booléens && et ||

Constantes locales

Les constantes locales ne sont pas prises en charge.

Alias d’importation

Les alias d’importation ne sont pas pris en charge.

Déclarations de variable

Vous ne pouvez pas déclarer de nouvelles variables explicites dans les fenêtres du débogueur. Toutefois, vous pouvez assigner de nouvelles variables implicites dans la fenêtre Exécution . La portée de ces variables implicites est celle de la session de débogage. Elles ne sont pas accessibles à l’extérieur du débogueur. Par exemple, l’instruction o = 5 crée implicitement une variable o et lui assigne la valeur 5. De telles variables implicites sont de type objet , sauf si le type peut être déduit par le débogueur.

Mots clés non pris en charge

  • AddressOf

  • End

  • Error

  • Exit

  • Goto

  • On Error

  • Resume

  • Return

  • Select/Case

  • Stop

  • SyncLock

  • Throw

  • Try/Catch/Finally

  • With

  • Mots clés de niveau espace de noms ou module, comme End Sub ou Module.