2010-09-22 12 views
34

Salve!Aggiunta messaggio per asserire

Sto cercando un modo per aggiungere messaggi personalizzati per affermare le affermazioni. Ho trovato questa domanda Add custom messages in assert? ma il messaggio è statico lì. Voglio fare qualcosa di simile:

assert((0 < x) && (x < 10), std::string("x was ") + myToString(x)); 

Quando l'asserzione fallisce voglio l'uscita normale più per esempio "x era 100".

+5

Penso che qui tu abbia una migliore risposta [http://stackoverflow.com/questions/3692954/add-custom-messages-in-assert) –

+2

Ugly hack: 'if (fail_condition) assert (!" Il mio messaggio ");' –

+0

@MarkKCowan, penso che il tuo "brutto attacco" sia in realtà molto meglio della patch "&&", perché mostra solo il messaggio :) – NL628

risposta

60

Sei sfortunato qui. Il modo migliore è definire la tua macro assert.

In sostanza, può assomigliare a questo:

#ifndef NDEBUG 
# define ASSERT(condition, message) \ 
    do { \ 
     if (! (condition)) { \ 
      std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \ 
         << " line " << __LINE__ << ": " << message << std::endl; \ 
      std::terminate(); \ 
     } \ 
    } while (false) 
#else 
# define ASSERT(condition, message) do { } while (false) 
#endif 

Questo definirà la ASSERT macro solo se il non-debug macro NDEBUG non è definito.

Allora devi usare in questo modo:

ASSERT((0 < x) && (x < 10), "x was " << x); 

Che è un po 'più semplice di quello che l'uso dal momento che non c'è bisogno di stringa i "x was " e x esplicitamente, questo viene fatto implicitamente dalla macro.

+4

Perché il do {} while (false)? – tauran

+4

@tauran: in questo modo è possibile inserire un punto e virgola dopo la macro quando lo si utilizza. –

+0

Perché non un 'do {} while (false)' per il caso '# else'? ;-) Spesso utile anche per visualizzare il codice sorgente di asserzione stringato 'condizione #. Rigorosamente, EXIT_FAILURE dovrebbe essere preferito anche a 1. +1 come si sta configurando come la migliore risposta. –

6
#define ASSERT_WITH_MESSAGE(condition, message) do { \ 
if (!(condition)) { printf((message)); } \ 
assert ((condition)); } while(false) 
7

Un'alternativa migliore è quello di insegnare il debugger di fermarsi asserzione quando non riesce, allora si potrebbe esaminare non solo il valore x, ma qualsiasi altra informazione tra cui stack di chiamate. Forse, questo è quello che stai davvero cercando. implementazione di esempio viene citato qui Ways to show your co-programmers that some methods are not yet implemented in a class when programming in C++

+0

+1 Non è quello che cercavo, ma potrebbe essere davvero utile un giorno. – tauran

2

Per ragioni di completezza, ho pubblicato un drop-in 2 file asseriscono macro implementazione in C++:

#include <pempek_assert.h> 

int main() 
{ 
    float min = 0.0f; 
    float max = 1.0f; 
    float v = 2.0f; 
    PEMPEK_ASSERT(v > min && v < max, 
       "invalid value: %f, must be between %f and %f", v, min, max); 

    return 0; 
} 

verrà chiesto con:

Assertion 'v > min && v < max' failed (DEBUG) 
    in file e.cpp, line 8 
    function: int main() 
    with message: invalid value: 2.000000, must be between 0.000000 and 1.000000 

Press (I)gnore/Ignore (F)orever/Ignore (A)ll/(D)ebug/A(b)ort: 

Dove

  • (I) gnore: ignorare l'asserzione corrente
  • Ignora (F) orever: ricordate il file e la linea dove l'affermazione licenziato e ignorarlo per il restante esecuzione del programma
  • Ignora (A) ll: ignorare tutte le asserzioni restanti (tutti i file e le linee)
  • (D) ebug: passare al debugger se attaccato, altrimenti abort() (su Windows, il sistema chiederà all'utente di collegare un debugger)
  • a (b) Ort: chiamare abort() immediatamente

È puoi saperne di più a questo proposito c'è:

Speranza che aiuta.

7

Ci sono alcuni vecchi trucchi per includere i messaggi senza scrivere le proprie routine:

La prima è questa:

bool testbool = false; 
assert(("this is the time", testbool)); 

C'è anche:

bool testbool = false; 
assert(testbool && "This is a message"); 

La prima si lavora, perché il risultato dell'espressione parents interna è il valore di 'testbool'. Il secondo funziona, perché il valore della stringa sarà diverso da zero.

0

percorrendo con la risposta di Konrad Rudolf si può fare un po 'più conciso con

#include <assert.h> 
#include <stdio.h> 
#define ASSERT(condition,...) assert(\ 
    condition|| \ 
    (fprintf(stderr,__VA_ARGS__)&&fprintf(stderr," at %s:%d\n",__FILE__,__LINE__)) \ 
); 

che funziona anche in C,

funziona utilizzando l'idea generale da alcune delle risposte alla domanda hai collegato, ma la macro ti permette di essere un po 'più flessibile

Problemi correlati