Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

DE L'IMPORTANCE DES ASSERT


Information sur la source

Catégorie :Astuces Niveau : Initié Date de création : 05/02/2004 Vu : 5 018

Note :
9 / 10 - par 3 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (4)
Ajouter un commentaire et/ou une note

Description

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

  • #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;
  • }
#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 !
 

Commentaires et avis

signaler à un administrateur
Commentaire de psycho le 06/02/2004 17:30:01

merci, j ai appris quelque chose de tres utile. Pour la peine je met 10, car c'est vraiment utile de savoir ca!!!
encore merci, et continue comme ca!
psycho

signaler à un administrateur
Commentaire de tibur le 06/02/2004 17:48:39

Encore un petit tips :

std::string s;
std::cin &gt;&gt; s;
assert(!std::cin.fail()&&"mot clef attendu");
switch(s){
case "nimp":
   std::cout &lt;&lt;" nimp ";
   break;
case "quit":
   std::cout &lt;&lt;" ciao ";
default:
   assert(!"C'est pas un mot clef valide !");
}

Notez bien le ! au debut de la chaine de char, dans le assert. Du coup, cela revient à assert(false) ce qui leve l'assertion fault.

tib

signaler à un administrateur
Commentaire de tibur le 06/02/2004 17:49:41

oups, j'ai oublié un break dans le case "quit" !
pas bien ...

signaler à un administrateur
Commentaire de magic_Nono le 10/12/2007 12:45:40 7/10

switch sur une chaine, j'aime bcp...

Sinon, sympa le coup de la chaine cste ajoutée à la condition, ça peut aider...

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,281 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.