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 assertmontre la condition qui a échoué, il affichera également votre message. Si cela ne suffit pas, vous pouvez écrire votre propre myAssertfonction ou macro qui affichera ce que vous voulez.
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));
Keith Thompson
3
Ce serait bien, cependant, de pouvoir imprimer les valeurs des variables, comme dans:assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
Frank
7
@Frank, printfrenvoie 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.
zneak
1
Mauvais code! Je ne comprends pas ça! Si a == b est faux, l'expression and doit également être fausse et, par conséquent, la chaîne ne doit pas être évaluée.
ragnarius
1
@TUIlover, ce n'est pas ainsi que fonctionnent les littéraux de chaîne C; ce sont des constantes de compilation et leur utilisation dans ce contexte est optimisée de manière triviale. Il n'y a aucun coût d'exécution.
zneak
45
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é)
C'est une excellente approche, avec un petit problème, il affichera "avertissement: l'opérande gauche de l'opérateur virgule n'a aucun effet" lorsqu'il est compilé en g ++ avec `-Wunused-value
v010dya
1
ou avec une macro: #ifndef m_assert #define m_assert (expr, msg) assert ((msg, expr)) #endif
Szymon Marczak
L'utilisation d'un wrapper de macro vous permet d'éviter l'avertissement gcc:#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Jander
25
Voici ma version de la macro assert, qui accepte le message et imprime tout de manière claire:
Je suis un peu confus. #Expr est-il traité comme une chaîne de substitution directe? Quelle est la différence entre #Expr et Expr?
Minh Tran
@MinhTran Supposons que votre condition d'assertion est 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.
Eugene Magdalits
Malheureusement, cette solution entraîne un comportement non défini en raison de l'utilisation d'identificateurs réservés.
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.
@Jichao, qu'entendez-vous par implémentation de l'interface d'assert?
Tarc
7
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.
"Puisque le lecteur de l'erreur d'assertion recherchera le fichier et la ligne de toute façon à partir du message d'erreur," - seulement s'ils sont diligents.
Jason S du
Seulement s'ils veulent corriger le bogue, vous voulez dire ... quel commentaire idiot
métamorphose
1
Non. Plus vous aidez les gens à voir le problème, plus ils auront de chances d'agir.
Jason S du
hausser les épaules Pas d' accord.
métamorphose du
2
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é
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:Puisque
assert
montre la condition qui a échoué, il affichera également votre message. Si cela ne suffit pas, vous pouvez écrire votre propremyAssert
fonction ou macro qui affichera ce que vous voulez.la source
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 commeassert(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:
(ceci a été copié à partir des commentaires ci-dessus, pour une meilleure visibilité)
la source
#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:
Maintenant, vous pouvez utiliser ceci
Et en cas d'échec, vous recevrez un message comme celui-ci:
Agréable et propre, n'hésitez pas à l'utiliser dans votre code =)
la source
x == y
. Ensuite, Expr se développeraif( !(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.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.
la source
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.:
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:
lit mieux que ça:
en termes d'analyse humaine du code ie. lisibilité. Pas non plus un hack de langue.
la source
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éla source
Pour vc, ajoutez le code suivant dans assert.h,
la source