De l'importance des assert

Contenu du snippet

Petit exemple demontrant l'importance des assertions en C++. Accessoirement, il montre comment on peux calculer une racine de maniere iterative (pas optimisé du tout !).

Source / Exemple :


#include <iostream>
#include <math.h>
#include <assert.h>

double racine(double d, double epsilon = 0.00000001);

int main(int argc, char**argv){
  double input;
  std::cin >> input;
  assert(!std::cin.fail()&&"Un nombre est attendu !");
  std::cout << "sqrt(" <<input <<") = " << racine(input) <<" " <<std::endl;
  return 0;
}

double racine(double d, double epsilon){
  assert(d>0&&"Impossible de calculer une racine negative !");
  double res = 1;
  double last = 0;
  for(;fabs(res-last)>epsilon;){
    last = res;
    res = (res + d) / (res + 1);
  }
  return res;
}

Conclusion :


Voici quelques explications sur la fonction assert. Elle prend en parametre un booleen. On doit considerer cela comme une "supposition" : si le booleen est vrai, le programme continue normalement son execution. Sinon, le programme s'arrete et la ligne à laquelle il a stopé est affichée. Si par exemple, on rentre le nombre -10, le resultat de l'execution est :

assertion "d>0&&"Impossible de calculer une racine negative !"" failed: file "main.cpp", line 16

Je suis sur que vous vous posez plusieurs question :

Pourquoi ajouter &&"Impossible de calculer une racine negative !" ? C'est tout simple : il permet de comprendre quelle est la cause de l'erreur. De plus, la chaine de caractere n'est pas nulle, donc le test n'est pas changé (equivaut à &&true).

Pourquoi ne pas simplement faire un :

if(d>0){
std::cerr <<"Impossible de calculer une racine negative !" <<std::endl;
exit(1);
}

Premierement, ce code ne nous donnera pas la ligne a laquelle l'erreur est localisée. Ensuite, l'avantage du assert est que ce code n'est tout simplement pas "inseré" dans le programme si l'on le compile en mode "release". C'est uniquement du debug.

Cette derniere remarque est un peu abusive, dans la mesure ou ce test doit s'effectuer meme en mode release (input de l'utilisateur). Par contre, si vous utilisez la fonction racine dans votre programme, ou si vous l'incluez dans une librairie, l'utilisateur de la fonction sera bien content de savoir qu'il a appelé une fonction avec des arguments non valides.

Pour conclure, je dirais : abusez de l'assert. Les gens utilisant votre code vous en seront reconnaissant. Il n'y a rien de plus frustrant que de s'appercevoire apres 1/2 heure de debug que la fonction qu'on appelle ne prend pas vraiment les parametres que l'on supposait !

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.