C'è un modo per aggiungere o modificare il messaggio generato da assert? Mi piacerebbe usare qualcosa di simile
assert(a == b, "A must be equal to B");
Quindi, il compilatore aggiunge riga , tempo e così via ...
È possibile?
C'è un modo per aggiungere o modificare il messaggio generato da assert? Mi piacerebbe usare qualcosa di simile
assert(a == b, "A must be equal to B");
Quindi, il compilatore aggiunge riga , tempo e così via ...
È possibile?
Risposte:
Un trucco che ho visto in giro è usare l' &&
operatore. Poiché un puntatore "è vero" se non è null, è possibile effettuare le seguenti operazioni senza alterare la condizione:
assert(a == b && "A is not equal to B");
Poiché assert
mostra la condizione non riuscita, verrà visualizzato anche il tuo messaggio. Se non è abbastanza, puoi scrivere la tua myAssert
funzione o macro che visualizzerà quello che vuoi.
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
restituisce un valore diverso da zero se viene stampato qualcosa, quindi potresti fare qualcosa del genere assert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, anche se a quel punto dovresti probabilmente scrivere il tuo wrapper di asserzione.
Un'altra opzione è quella di invertire gli operandi e utilizzare l'operatore virgola. Hai bisogno di parentesi extra in modo che la virgola non sia trattata come delimitatore tra gli argomenti:
assert(("A must be equal to B", a == b));
(questo è stato copiato dai commenti sopra, per una migliore visibilità)
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Ecco la mia versione di assert macro, che accetta il messaggio e stampa tutto in modo chiaro:
#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();
}
}
Ora puoi usare questo
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
E in caso di fallimento riceverai un messaggio come questo:
Asserzione non riuscita: MyFunction: richiede un argomento non nullo
Previsto: ptr! = Nullptr
Fonte: C: \ MyProject \ src.cpp, riga 22
Bello e pulito, sentiti libero di usarlo nel tuo codice =)
x == y
. Quindi Expr si espanderà if( !(x == y))
e qui è dove viene verificata la condizione, e #Expr si espanderà in stringa letterale "x == y"
, che quindi inseriremo nel messaggio di errore.
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Puoi usarlo direttamente o copiare il codice di Boost. Si noti inoltre che Boost assert è solo intestazione, quindi è possibile prendere quel singolo file se non si desidera installare tutto Boost.
Dato che la risposta di zneak contorna un po 'il codice, un approccio migliore è semplicemente commentare il testo della stringa di cui stai parlando. vale a dire .:
assert(a == b); // A must be equal to B
Poiché il lettore dell'errore assert cercherà comunque il file e la riga dal messaggio di errore, vedrà la spiegazione completa qui.
Perché, alla fine della giornata, questo:
assert(number_of_frames != 0); // Has frames to update
legge meglio di così:
assert(number_of_frames != 0 && "Has frames to update");
in termini di analisi umana del codice, ad es. leggibilità. Inoltre non è un hack di lingua.
assert è una combinazione macro / funzione. è possibile definire il proprio macro / funzione, utilizzando __FILE__
, __BASE_FILE__
, __LINE__
ecc, con la propria funzione che prende un messaggio personalizzato
Per vc, aggiungi il seguente codice in assert.h,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )