Existe-t-il un moyen d'ajouter ou de modifier le message lancé par assert? J'aimerais utiliser quelque chose comme
assert(a == b, "A must be equal to B");
Ensuite, le compilateur ajoute la ligne , l' heure et ainsi de suite ...
C'est possible?
Existe-t-il un moyen d'ajouter ou de modifier le message lancé par assert? J'aimerais utiliser quelque chose comme
assert(a == b, "A must be equal to B");
Ensuite, le compilateur ajoute la ligne , l' heure et ainsi de suite ...
C'est possible?
Réponses:
Un hack que j'ai vu est d'utiliser l' &&
opérateur. Étant donné qu'un pointeur «est vrai» s'il n'est pas nul, vous pouvez effectuer les opérations suivantes sans modifier la condition:
assert(a == b && "A is not equal to B");
Puisque assert
montre la condition qui a échoué, il affichera également votre message. Si cela ne suffit pas, vous pouvez écrire votre propre myAssert
fonction ou macro qui affichera ce que vous voulez.
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
renvoie une valeur différente de zéro s'il imprimait quelque chose, vous pouvez donc faire quelque chose comme assert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, bien qu'à ce stade, vous devriez probablement écrire votre propre wrapper d'assert.
Une autre option consiste à inverser les opérandes et à utiliser l'opérateur virgule. Vous avez besoin de parenthèses supplémentaires pour que la virgule ne soit pas traitée comme un délimiteur entre les arguments:
assert(("A must be equal to B", a == b));
(ceci a été copié à partir des commentaires ci-dessus, pour une meilleure visibilité)
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Voici ma version de la macro assert, qui accepte le message et imprime tout de manière claire:
#include <iostream>
#ifndef NDEBUG
# define M_Assert(Expr, Msg) \
__M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
# define M_Assert(Expr, Msg) ;
#endif
void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
if (!expr)
{
std::cerr << "Assert failed:\t" << msg << "\n"
<< "Expected:\t" << expr_str << "\n"
<< "Source:\t\t" << file << ", line " << line << "\n";
abort();
}
}
Maintenant, vous pouvez utiliser ceci
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
Et en cas d'échec, vous recevrez un message comme celui-ci:
Échec de l'assertion: MyFunction: nécessite un argument non nul
Attendu: ptr! = Nullptr
Source: C: \ MyProject \ src.cpp, ligne 22
Agréable et propre, n'hésitez pas à l'utiliser dans votre code =)
x == y
. Ensuite, Expr se développera if( !(x == y))
et c'est là que la condition est vérifiée, et #Expr se développera en littéral de chaîne "x == y"
, que nous mettons ensuite dans un message d'erreur.
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Vous pouvez soit l'utiliser directement, soit copier le code de Boost. Notez également que l'assertion de Boost est uniquement un en-tête, vous pouvez donc simplement récupérer ce fichier unique si vous ne souhaitez pas installer tout Boost.
Comme la réponse de zneak complique quelque peu le code, une meilleure approche consiste simplement à commenter la chaîne de texte dont vous parlez. c'est à dire.:
assert(a == b); // A must be equal to B
Puisque le lecteur de l'erreur d'assertion recherchera de toute façon le fichier et la ligne à partir du message d'erreur, il verra l'explication complète ici.
Parce qu'en fin de compte, ceci:
assert(number_of_frames != 0); // Has frames to update
lit mieux que ça:
assert(number_of_frames != 0 && "Has frames to update");
en termes d'analyse humaine du code ie. lisibilité. Pas non plus un hack de langue.
assert est une combinaison macro / fonction. vous pouvez définir votre propre macro / fonction, en utilisant __FILE__
, __BASE_FILE__
, __LINE__
etc, avec votre propre fonction qui prend un message personnalisé
Pour vc, ajoutez le code suivant dans assert.h,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )