Le débogueur intégré à Visual Studio est un outil puissant qui vous sera très utile tout au long de votre carrière. Il permet de voir ce qui se passe dans notre programme, une étape à la fois, en examinant le contenu des variables pendant l'exécution. C'est idéal pour résoudre des bogues étranges qu'on n'arrive pas à s'expliquer en regardant simplement le résultat de l'exécution.
Un point d'arrêt (breakpoint) est une ligne dans le code où vous voulez arrêter l'exécution normale du programme pour commencer à déboguer. Vous ne pourrez rien déboguer si vous n'avez pas au moins placé un point d'arrêt. On place un point d'arrêt simplement en cliquant dans la marge de gauche de notre code.
Il est possible de placer autant de points d'arrêt que désiré. On peut évidemment les enlever si nécessaire, simplement en cliquant dessus.
Normalement, nous utilisons par défaut l'exécution sans débogage (Ctrl-F5), puisque ce mode fait une pause une fois l'exécution terminée, ce qui nous permet de voir le contenu de la console avant qu'elle soit fermée.
Si on veut utiliser les points d'arrêt, il nous faudra toutefois utiliser "Démarrer le débogage" (F5), sinon ils seront ignorés. On peut donc laisser les points d'arrêt en place et choisir de les utiliser ou non.
L'idée de mettre un point d'arrêt est de pouvoir ensuite suivre l'exécution de votre programme un pas à la fois. Pour ce faire, on appuie sur F5 (démarrer le débogage) et le programme s'exécute normalement jusqu'à ce qu'il atteigne le premier point d'arrêt. Ensuite, l'exécution est suspendue, comme mise à pause. Votre code revient à l'avant-plan et une flèche jaune apparaît sur le point d'arrêt -- la ligne de code est également surlignée:
La flèche jaune indique la ligne qui sera la prochaine à être exécutée. L'exécution est donc suspendue juste avant l'exécution de la ligne où se trouve le point d'arrêt. Vous pouvez alors:
Notez qu'il existe des icônes dans la barre de boutons qui permettent aussi de réaliser ces tâches:
Plutôt que de devoir constamment passer sa souris sur une variable pour la voir changer, on peut utiliser la fenêtre d'espions pour qu'elle soit affichée pour nous en permanence. La fenêtre d'espions apparaît normalement en dessous de la fenêtre du code pendant qu'on est en débogage. Si ce n'est pas le cas, on peut la faire apparaître en faisant Déboguer -> Fenêtre -> Espions -> Espion 1 (notez qu'on peut en ouvrir 4 différentes, toutes équivalentes).
On ajoute un espion en:
On peut y mettre:
Notez que les expressions n'ont pas besoin d'être des expressions directement tirées du code. Les variables, par contre, doivent être visibles au point du code où on est rendu en ce moment (pensez à la portée des variables locales).
Lorsqu'une valeur vient de changer (au dernier pas), elle devient rouge. Lorsqu'elle est pareille à ce qu'elle était au pas précédent, elle est noire.
En cliquant sur un point d'arrêt avec le bouton de droite, on peut choisir "Condition" et définir une condition pour que le point d'arrêt s'active. On peut aussi passer le pointeur de la souris par-dessus le point d'arrêt et cliquer sur la roue d'engrenage qui apparaît alors:
Tant que la condition n'est pas vraie, le point d'arrêt est ignoré. Idéal pour s'arrêter à un moment précis d'une boucle, vous le constaterez lorsque vous en ferez!
On peut placer dans la boîte n'importe quelle expression relationnelle, qui peut utiliser des variables visibles à cet endroit du code. À chaque passage au point d'arrêt, la condition sera évaluée. Si elle est fausse, le point sera ignoré et l'exécution continuera. Si elle est vraie, le point d'arrêt s'activera et l'exécution sera suspendue.
Optionnellement, on peut également inscrire uniquement le nom d'une variable dans la case de condition et choisir "En cas de modification" dans la liste déroulante. Le point d'arrêt s'activera si la variable donnée n'a pas la même valeur que lors du dernier passage au point d'arrêt. Il faut toutefois savoir que la première fois que la variable est modifiée sur cette ligne ne comptera pas et n'activera pas le point d'arrêt. Cette utilisation n'a donc de sens que dans un contexte de répétitive.
Il est aussi possible de choisir "Nombre d'accès" plutôt que "Expression conditionnelle" afin de faire en sorte que le point d'arrêt s'active après un certain nombre de passage sur cette ligne (encore une fois, c'est surtout utile dans une répétitive). On peut alors demander au point d'arrêt de s'activer lorsque le nombre d'accès est égal à une valeur donnée, plus grand ou égal à une valeur donnée, ou un multiple d'une valeur donnée (pour ces cas où le programme semble agir étrangement une fois sur 3...)
L'option "Filtre" permet d'activer le point d'arrêt lorsque le programme est exécutée sur un ordinateur précis, dans un processus précis ou dans un thread précis, une utilisation qui sera bien peu courante dans le cadre de votre formation.
Une fois créé, un point d'arrêt conditionnel a l'air de ça:
Une assertion est la vérification d'une condition essentielle à la bonne marche du programme, vérification qui ne sera faite que pendant la phase de développement et pas pendant l'utilisation régulière du programme terminé.
L'idée est de valider une certaine condition sans laquelle rien ne peut fonctionner et tout arrêter si jamais la condition est fausse. Mais attention! On ne doit pas utiliser les assertions pour valider les intrants fournis par l'usager, puisque les assertions seront ignorées lorsque le programme sera entièrement terminé. On validera plutôt l'état de variables internes, dont nous sommes seuls responsables du contenu, afin de nous aider à identifier les situations problématiques pendant que l'on débogue et qu'on teste notre programme.
Une assertion, en C++, s'écrit simplement comme ceci:
assert(condition);
La condition peut être une expression relative ou une expression logique, qui peut être réduite à true ou false, exactement comme la condition qu'on placerait dans un if. Par exemple:
assert(Compteur < 100);
Ou:
assert(Diviseur != 0);
Au moment où la ligne est exécutée, la condition est vérifiée. Si elle est fausse, le programme s'arrête immédiatement et affichera un message d'erreur correspondant à la condition:
Assertion failed: Diviseur != 0
N'oubliez pas d'inclure la bibliothèque assert.h si vous désirez utiliser les assertions:
#include <assert.h>
Depuis le début, nous compilons toujours en mode Debug, simplement parce que c'est l'option par défaut. Il y a des différences importantes entre les deux modes:
Debug:
Release:
On utilise normalement le mode Release une fois que le débogage est entièrement terminé, que les tests sont satisfaisants et que l'on s'apprête à remettre le programme aux utilisateurs. Comme les assertions sont ignorées, on peut simplement les laisser là et compiler en mode Release comme si de rien n'était.
On change le mode simplement en utilisant la liste déroulable au centre de la barre d'outils:
Prenez votre solution à votre exercice 2.5 du cours d'algorithmie.