Gestion des erreurs

Si vous souhaitez en savoir plus sur la gestion des exceptions, je vous suggère d'examiner Exceptions.html. Pour la pratique de la programmation au sens large, voir Pratique-programmation.html

La gestion des erreurs est un drôle d'oiseau. Il s'agit d'une chose importante, dont on vante les vertus et à laquelle on doit porter attention, or dans les notes de cours (incluant les miennes) on tend à la négliger ou à l'escamoter, par souci de simplicité.

Quelques réflexions d'autres auteurs sur le sujet :

Assertions dynamiques

« Using assertions in code is a way of revealing assumptions, but perhaps not in the way most developers think.

Developers normally think in terms of the content of the assertion itself and a formal idea of documenting, in hard form, a constraint expected or required of the code. » (Kevlin Henney, source)

Une assertion est un état qu'une fonction tient pour acquis et qui doit s'avérer pour que son exécution se poursuive. Les assertions dynamiques sont les plus connues d'entre elles, mais il existe aussi des assertions statiques dans certains langages (en particulier C++).

Un exemple simple d'assertion dynamique serait :

#include <cassert>
#include <algorithm>
template <class T>
   char* copie_brute(char *dest, std::size_t capacite, const T &val) {
      using std::copy;
      //
      // une exception sera préférable si le programme doit
      // être capable de récupérer; une assertion est préférable
      // si le programme est dans un état tel que récupérer serait
      // plus dangereux que terminer brusquement. Ici, on présume
      // être dans un contexte scientifique
      //
      assert(sizeof(T)<=capacite);
      auto p = reinterpret_cast<const char*>(&val);
      copy(p, p + sizeof(T), dest);
      return dest + sizeof(T);
   }

Si vous vous demandez pourquoi j'ai utilisé std::copy plutôt que std::memcpy() ici, voir Traits et optimisation.

La prudence...

Mon grand ami Pez (Jean-François Pezet) m'a raconté un incident vécu dans l'un de ses milieux de travail il y a quelques années. Plusieurs compilateurs implémentent assert() sous forme d'une macro qui disparaît lors de compilation en mode production (Release), ce qui fait que les « invocations » d'assert() sont alors conservées en période de mise au point (Debug) et éliminées du code généré pour livraison commerciale.

Conséquence : il est essentiel de ne pas écrire de programmes dépendant d'opérations effectuées dans une invocation de assert(), ces opérations étant susceptibles de ne pas apparaître dans la version finale du produit.

Ainsi, plutôt que...

// b n'est pas initialisé
int b;
// Initialiser b ET vérifier que getValue() retourne une valeur != 0
// (attention: ne fonctionne qu'en mode Debug!)
assert(b = getValue());
// En mode Release, b n'est pas encore initialisée
f(b);

...où l'appel f(b) mène à ce qu'on nomme du Undefined Behavior, il faut prendre soin d'écrire...

// déclarer et initialiser b
int b = getValue();
// Vérifie que getValue() ait bien retourné une valeur != 0
assert(b);
// Tout est sous contrôle
f(b);

Lectures complémentaires

Résilience

La résilience d'un système, d'un programme ou d'un composant logiciel est un terme général intégrant la robustesse et la tolérance aux pannes. Sous ce chapeau se groupent plusieurs aspects de la gestion des erreurs :

La résilience est une caractéristique architecturale et conceptuelle, qui implique le matériel, l'encapsulation, le bon design d'une API, etc. Les assertions dynamiques font partie des mécanismes de résilience d'un programme, tout comme les assertions statiques, les codes d'erreurs et les exceptions.

Ce que je fais, personnellement

Si un logiciel doit planter, mieux vaut s'assurer qu'il plante rapidement. Dans un monde idéal :

Notez que ces « consignes » constituent pour moi un guide général, pas une loi à laquelle il faut obéir ou un dogme auquel il faut adhérer à tout prix. Par exemple, les exceptions ne peuvent pas toujours être utilisées en pratique, du moins dans l'état actuel de nos connaissances, ayant un caractère légèrement imprévisible qui les rend impropres (pour le moment) dans les systèmes temps réel les plus stricts. Notez la nuance  : le traitement d'exceptions n'est pas lent, mais il est ardu de déterminer a priori le temps maximal dont il aura besoin; le problème en est un de prévisibilité, pas de vitesse.

Lectures complémentaires

Pour d'autres perspectives sur le sujet :


Valid XHTML 1.0 Transitional

CSS Valide !