web-dev-qa-db-fra.com

Ajouter des messages personnalisés dans assert?

Existe-t-il un moyen d’ajouter ou de modifier le message envoyé par assert? J'aimerais utiliser quelque chose comme

assert(a == b, "A must be equal to B");

Ensuite, le compilateur ajoute ligne, heure et ainsi de suite ...

C'est possible?

111
Killrazor

Un hack que j'ai vu est d'utiliser le && opérateur. Puisqu’un pointeur "est vrai" s’il n’est pas nul, vous pouvez procéder comme suit sans modifier la condition:

assert(a == b && "A is not equal to B");

Puisque assert indique la condition qui a échoué, votre message s'affichera également. Si cela ne suffit pas, vous pouvez écrire votre propre fonction ou macro myAssert qui affichera tout ce que vous voulez.

209
zneak

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 séparateur entre les arguments:

assert(("A must be equal to B", a == b));

(ceci a été copié des commentaires ci-dessus, pour une meilleure visibilité)

37
Andrei Bozantan

Voici ma version de la macro assert, qui accepte le message et affiche le 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 cette

M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");

Et en cas d'échec, vous recevrez un message comme celui-ci:

L'assertion a échoué: MyFunction: nécessite un argument non nul

Attendu: ptr! = Nullptr

Source: C:\MyProject\src.cpp, ligne 22

Nice and clean, n'hésitez pas à l'utiliser dans votre code =)

19
Eugene Magdalits
BOOST_ASSERT_MSG(expre, msg)

http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html

Vous pouvez utiliser cela directement ou copier le code de Boost. Notez également que Boost assert est uniquement en-tête, vous pouvez donc récupérer ce fichier si vous ne souhaitez pas installer l'intégralité de Boost.

18
Zero

Comme la réponse de zneak complique quelque peu le code, une meilleure approche consiste simplement à commenter le texte de chaîne dont vous parlez. c'est à dire.:

assert(a == b); // A must be equal to B

Etant donné que le lecteur de l'erreur d'assertion va chercher le fichier et la ligne dans le message d'erreur, il verra l'explication complète ici.

Parce que, en fin de journée, ceci:

assert(number_of_frames != 0); // Has frames to update

lit mieux que cela:

assert(number_of_frames != 0 && "Has frames to update");

en termes d'analyse humaine du code, à savoir. lisibilité. Aussi pas un hack de langue.

7
metamorphosis

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é

1

Pourquoi personne n'a mentionné la solution la plus propre?

bool AMustBeEqualToB = (a == b);
assert(AMustBeEqualToB);