Mot cle ASSERT

Mot cle ASSERT - C++ - Programmation

Marsh Posté le 15-05-2006 à 11:20:21    

Bonjour,  
 
pouvais vous m'eclaicir quant-à l'utilisation du mot clé ASSERT?
Est-ce bien pour faire des vérifications sur ce qu'on passe en paramêtre?
Est-ce que ça retourne quelque chose?
Est-ce obligatoire dans un programme du genre :

Code :
  1. ...
  2. nIndex = i - ID_FILE_MRU_FILE1;
  3.     ASSERT((*m_pRecentFileList)[nIndex].GetLength() != 0);
  4. ...


 
Merki

Reply

Marsh Posté le 15-05-2006 à 11:20:21   

Reply

Marsh Posté le 15-05-2006 à 11:31:54    

c'est un mot clé utilisé pour s'assurer qu'un comportement est bien celui attendu. ainsi dans ton exemple, si le résultat de *m_pRecentFileList)[nIndex].GetLength() est égal à 0, alors tu auras un message du genre "Assertion failed". tu aurais obtenu le même comportement avec un test du genre :

Code :
  1. if ((*m_pRecentFileList)[nIndex].GetLength() == 0)
  2.    AfxMessageBox("L'assertion a échouée" );


Attention : à ma connaissance, seules les MFC disposent de ce mot clé

Message cité 1 fois
Message édité par Harkonnen le 15-05-2006 à 11:32:53

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2006 à 11:35:29    

:bounce:  
merci beaucoup, c'est plus clair pour moi maintenant!

Reply

Marsh Posté le 15-05-2006 à 11:39:49    

ASSERT n'est pas un mot clé, c'est une macro qui permet de tester une expression et de stopper le programme si l'expression est fausse.
 
suivant l'environnement/compilo/le projet le test peut ne se faire qu'en DEBUG, afin de valider la cohérence de certains choses qui devraient a la base ne pas poser de problèmes.
 
si tu sais que l'on peut passer des trucs débiles a une fonction, il vaux mieux la protégér normalement plustôt qu'avec un ASSERT:
 
 

Code :
  1. extern MachinBidule *General;
  2. bool ProcessMachin( Machin *truc )
  3. {
  4.      ASSERT( General );      // le General NE PEUT qu'exister, autrement ce serait un problème grave au niveau de l'état interne de l'application
  5.      // truc doit exister mais on vérifies quand même, et son état interne
  6.      if( !truc || !truc->etat_valide )
  7.         return false;
  8.     if( General->Track( truc ) )
  9.        ....
  10.      ...
  11.      ....
  12.      return true;
  13. }


 
maintenant si tu pars que "truc" doit exister et que c'est à l'appellant de pas faire de truc débile, a ce moment tu mets un:
ASSERT( truc );
 
un ASSERT() est plus là pour tester la coherence interne de l'application lors du développement.
autrement si tu dois tester la "sanité" d'objets/etats en production, c'est sans ASSERT, et là dans ce cas tu retourne un code d'erreur (false, -1, un enum), ou tu lèves une exception avec un throw, qui sera prise en compte par le code appellant.

Message cité 1 fois
Message édité par bjone le 15-05-2006 à 11:43:59
Reply

Marsh Posté le 15-05-2006 à 11:41:59    

bjone a écrit :

ASSERT n'est pas un mot clé, c'est une macro qui permet de tester une expression et de stopper le programme si l'expression est fausse.


en C++ effectivement, en Java c'est un mot clé :D


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2006 à 11:43:01    

assert n'est pas un mot cle mais une macro definie dans cassert, on peut aussi utiliser BOOS_ASSERT (boost/assert.hpp) qui permet de gerer l'echec de l'assertion (en definissant boost::assertion_failed)  d'une maniere plus propre que l'appel de la fonction abort fait par assert

Reply

Marsh Posté le 15-05-2006 à 15:22:34    

Harkonnen a écrit :

Attention : à ma connaissance, seules les MFC disposent de ce mot clé


:non:  sous unix il y egalement une fonction assert dans un bibliotheque (je ne sais plus laquelle)
 
Par contre, le assert c'est plutot pour faire du C, en C++ on utilise plutot les exceptions non ? C'est plus facilement gerable


---------------
"Tant qu'il y aura des hommes il y aura de comptoirs"
Reply

Marsh Posté le 15-05-2006 à 17:36:39    

1/ non donc c'est une marcro
2/ en C++ ca fonctionne très bien, on a pas de raison de s'en priver.

Reply

Marsh Posté le 15-05-2006 à 18:10:26    

_darkalt3_ a écrit :


2/ en C++ ca fonctionne très bien, on a pas de raison de s'en priver.


 
en C++ on prefere jeter une exception, donc avec BOOST_ASSERT c'est mieux

Reply

Marsh Posté le 15-05-2006 à 18:12:17    

pour moi l'ASSERT de base, c'est pour faire des vérifications de cohérence interne en debug, pas en release.

Message cité 1 fois
Message édité par bjone le 15-05-2006 à 18:13:31
Reply

Marsh Posté le 15-05-2006 à 18:12:17   

Reply

Marsh Posté le 15-05-2006 à 18:15:40    

+1


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2006 à 19:19:25    

bjone a écrit :

pour moi l'ASSERT de base, c'est pour faire des vérifications de cohérence interne en debug, pas en release.


 
ouai, dans ce cas si une assertion echoue le plus raisonnable et d'arreter l'execution du code -> abort (et surtout ne pas lancer d'exception)  :ange:

Reply

Marsh Posté le 15-05-2006 à 19:43:38    

skelter a écrit :

en C++ on prefere jeter une exception, donc avec BOOST_ASSERT c'est mieux


si on utilise boost


---------------
Töp of the plöp
Reply

Marsh Posté le 15-05-2006 à 22:09:27    

_darkalt3_ a écrit :

si on utilise boost


on devrait tous :o

Reply

Marsh Posté le 15-05-2006 à 22:38:27    

on ira tous au paradis, même toi....

Reply

Marsh Posté le 16-05-2006 à 09:10:38    

Joel F a écrit :

on devrait tous :o


faut le dire aux dissaïdorzes :o

Reply

Marsh Posté le 20-05-2006 à 16:04:09    

ASSERT est une macro MFC active uniquement avec le flag _DEBUG. Attention à ne surtout pas passer en argument une instruction de traitement car dans ce cas l'instruction n'est pas compilée en release (flag NDEBUG à la place de _DEBUG)
 
Il existe une version "toute cible confondue" de ASSERT : VERIFY. Personnellement je n'utilise que ASSERT qui est un outil puissant pour la programmation défensive, c'est à dire la programmation des pré-conditions et post-conditions. Cependant les assertions ne sont pas  parfaites et il est assez pénible de ne pas pouvoir afficher un message d'erreur allant de paire avec l'assertion.
 
en c++ (pur) il existe aussi une fonction assert (en minuscules cette fois) présente dans <cassert>
 
Ca existe aussi en Java.
 
Ce qu'il faut retenir : les assertions sont connectées à la notion de programmation défensive. Elles sont présentes dans tous les langages de programmation récents et quelques fois débrayables (java par exemple)


Message édité par slash33 le 20-05-2006 à 16:10:38
Reply

Marsh Posté le 28-05-2007 à 21:39:25    

+1
 
Pour aller plus loin, il est vrai que les assert sont utilisés dans la programmation par contrat (mais il n'y a pas véritablement de contrat en C++)
 
On utilise souvent les assert pour vérifier les arguments passés en paramètres à une méthode. Cela n'est bien de le faire que dans les méthodes protected ou private. La gestion des exceptions est plus appropriée (car entre autres beaucoup plus propre) dans les méthodes publics. Il n'y a aucune restriction et même des encouragements à utiliser les asserts dans tous les autres cas (Pré-condition dans les méthodes protected ou private, post-condition dans les méthodes publiques, protected, ..., etc).
 
Bref, éclatez vous avec les assert, mais jamais en précondition dans les méthodes publics (on le saura).
 
Autre chose, ils ne sont effectifs qu'en debug. Des que vous passez en release, ils sont inefficaces...

Reply

Marsh Posté le 30-05-2007 à 00:32:06    

rage63 a écrit :

Autre chose, ils ne sont effectifs qu'en debug. Des que vous passez en release, ils sont inefficaces...


plus précisément, c'est la macro NDEBUG qui contrôle l'expansion de assert.
On est libre de définir NDEBUG en release ou non.

Reply

Marsh Posté le 30-05-2007 à 00:43:05    

skelter a écrit :

en C++ on prefere jeter une exception, donc avec BOOST_ASSERT c'est mieux


J'utilise une macro MY_ASSERT_MSG( check, msg )  maison, qui s'expend en :
 
Assert<std::runtime_error>( check, msg );
[l'équivalent de if( !check ) throw std::runtime_error( msg )]
si une macro EXCEPTION_ON_ASSERT est définie.  
 
Sinon, la macro s'expend en assert( check && msg ), qui dépend de NDEBUG.
 
ça me convient à peu près, mais si on peut faire mieux avec BOOST_ASSERT, je prends ...

Reply

Marsh Posté le 30-05-2007 à 22:08:59    

rage63 a écrit :

Cela n'est bien de le faire que dans les méthodes protected ou private. La gestion des exceptions est plus appropriée (car entre autres beaucoup plus propre) dans les méthodes publics.


 
Tu peux préciser, stp ? Je ne vois pas en quoi la distinction private~protected / public est pertinente.  
 
Pour moi assert = "test d'une condition qui devrait toujours être vraie quand le logiciel sera débuggé" (c'est une aide au développement et dans le logiciel en production on virera les assert) et exception = "gestion des erreurs qui peuvent effectivement arriver dans la limite des spécifications", et l'accessibilité des méthodes n'a rien à y voir. Je peux me tromper, ceci dit.

Reply

Marsh Posté le 02-06-2007 à 19:35:15    

j'ai un proleme...quand je copie le code de bjone sur le logiciel DevC++
je compile , il me dit qu'il y a un proleme dans ce code , est-ce que ce probleme sur le code ou sur le logiciel ???

Reply

Marsh Posté le 02-06-2007 à 21:15:43    

boulgakov a écrit :

Tu peux préciser, stp ? Je ne vois pas en quoi la distinction private~protected / public est pertinente.


Il parait probablement du contrôle des arguments et effectivement les arguments d'une méthode publique doivent être contrôlés sans possibilité de les contourner. Remarquez j'ai des collègues qui découvrent les assertions, qui ne savent pas ce qu'est la programmation par contrat et qui mettent des exceptions en réponse à des comportements prévus, prévisibles et redondants (résultat j'ai une pile d'exception - non typées en plus - qui s'affichent dans le deboggueur)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed