Aggiungere messaggi personalizzati affermano?

C’è un modo per aggiungere o modificare il messaggio lanciato da far valere? Vorrei utilizzare qualcosa di simile

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

Quindi, il compilatore aggiunge linea, tempo e così via…

È possibile?

  • Si può definire una macro, come questo.
InformationsquelleAutor Killrazor | 2010-09-11

 

8 Replies
  1. 203

    Un trucco che ho visto in giro è quello di utilizzare il && operatore. Dal momento che un puntatore “è vero”, se non nullo, è possibile effettuare le seguenti operazioni, senza alterare la condizione:

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

    Dal assert mostra la condizione di errore, verrà visualizzato il messaggio di troppo. Se non è sufficiente, è possibile scrivere il proprio myAssert funzione o macro che consente di visualizzare ciò che si vuole.

    • Un’altra opzione è quella di invertire la operandi e utilizzare l’operatore virgola. Hai bisogno di un’ulteriore parentesi in modo che la virgola non è trattata come un delimitatore tra gli argomenti: assert(("A must be equal to B", a == b));
    • Sarebbe bello, anche se, per essere in grado di stampare i valori delle variabili, ad esempio: assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
    • restituisce un valore diverso da zero se è stampato nulla, quindi si potrebbe fare qualcosa di simile assert(a == b && printf("a (%i) is not equal to b (%i)", a, b)), anche se a quel punto probabilmente si dovrebbe scrivere il proprio affermare wrapper.
    • Il codice cattivo! Non ho capito questo! Se a==b è falso, l’e-espressione dovrebbe anche essere false, e, quindi, la stringa non deve essere valutato.
    • de Morgan, si applica la legge qui, e dato che la stringa di sempre “restituisce” true, è possibile modificare il risultato della condizione. È nel codice sorgente solo come annotazione, dal momento che il assert macro stampe tutto assert linea quando non riesce.
    • non funziona per me, sto utilizzando ` Affermare::AreEqual(2, HelloWorld::due storielle a riguardo());` possibile simile principio, essere applicato anche a questa sintassi?
    • no, dovrai controllare la condizione.
    • mi dispiace ma io non la seguo, sto seguendo questo tutorial codeproject.com/Tips/1085171/… potete per favore postare il link a chiarire la vostra raccomandazione. Grazie
    • Io non sto raccomandando nulla; non è possibile utilizzare questa soluzione per un messaggio. Funziona perché a == b && "foo" è la stessa a == b. Se il codice non fa che il confronto in sé, che non si può fare.

  2. 35

    Un’altra opzione è quella di invertire la operandi e utilizzare l’operatore virgola. Hai bisogno di un’ulteriore parentesi in modo che la virgola non è trattata come un delimitatore tra gli argomenti:

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

    (questo è stato copiato da sopra i commenti, per una migliore visibilità)

    • Questo è un ottimo approccio, con un piccolo problema, viene visualizzato “avvertenza: l’operando di sinistra della virgola operatore non ha alcun effetto” quando viene compilato in g++ con `-Wunused-valore
    • o con una macro: #ifndef m_assert #define m_assert(expr, msg) assert((msg, expr)) #endif
    • Utilizzando una macro wrapper che permette di evitare il gcc attenzione: #define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
  3. 19

    Ecco la mia versione di affermare macro, che accetta il messaggio e stampe 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, è possibile utilizzare questo

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

    E in caso di errore verrà visualizzato un messaggio simile a questo:

    Assert failed:  MyFunction: richiede l’argomento non null

    Previsto: ptr != nullptr

    Fonte: C:\MyProject\src.cpp linea 22

    Bella e pulita, sentitevi liberi di utilizzare nel codice =)

    • Una bella. Molto utile
    • Io sono un po ‘ confuso. È #Expr trattato come una stringa per sostituzione diretta? Qual è la differenza tra #Expr e Espr?
    • Supponiamo che il vostro affermare la condizione è x == y. Quindi Expr si espandono in if( !(x == y)) e questo è dove la condizione è verificata, e #Expr si espandono in stringa letterale "x == y", che abbiamo poi messo nel messaggio di errore.
  4. 18
    BOOST_ASSERT_MSG(expre, msg)

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

    Si potrebbe utilizzare direttamente o copia Spinta del codice. Anche nota Boost asserzione è solo nell’intestazione, quindi, si può solo afferrare quel singolo file se non si desidera installare tutti i Boost.

    • nota boost bisogno di voi per implementare l’asserzione di interfaccia.
    • che cosa si intende per attuare l’asserzione di interfaccia?
  5. 7

    Come zneak risposta convolutes il codice un po’, un approccio migliore è quello di mero commento la stringa di testo che si sta parlando. es.:

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

    Poiché il lettore di affermare errore di cercare il file e la riga comunque da il messaggio di errore, verrà visualizzata la spiegazione completa qui.

    Perché, alla fine della giornata, questo:

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

    legge meglio di questo:

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

    in termini umani di analisi del codice di ie. la leggibilità. Inoltre, non è una lingua hack.

    • “Poiché il lettore di affermare errore di cercare il file e la riga comunque da il messaggio di errore” — solo se sono diligenti.
    • Solo se si vuole risolvere il bug si intende… che stupido commento
    • No. Il più facile è farlo per le persone a vedere il problema, il più è probabile che sarà entrare in azione.
    • scrollata di spalle non sono d’accordo.
  6. 1

    asserzione è una macro/funzione di combinazione. è possibile definire le proprie macro/funzione, utilizzando __FILE__, __BASE_FILE__, __LINE__ ecc, con una propria funzione che accetta un messaggio personalizzato

  7. 0

    Perché nessuno ha menzionato la soluzione più pulita?

    bool AMustBeEqualToB = (a == b);
    assert(AMustBeEqualToB);
    • Se l’espressione non può essere dimostrato di non avere effetti collaterali (ad esempio, una chiamata di funzione), quindi questo metodo forza compilatore di includere la valutazione anche in una build di rilascio in cui afferma devono essere ignorati. E come per il “cleannes” – che il codice sembra la cosa migliore è una preferenza personale, ma dubito che molte persone lo considerano più leggibile di un commento, accanto ad esso.
    • Ma se ci mettete un commento, non sarà stampato su console dopo le affermazioni di fallimento.
    • Sì, è vero, ma – come sottolineato da altri, se si ottiene l’errore di asserzione, è estremamente probabile che la prima cosa da fare è visitare riga di codice errata. La maggior parte di voi non sa nemmeno cosa a e b mezzo, se non si guarda il contesto in cui asserzione non riuscita, quindi, è necessario visitare il codice comunque. E se asserzione dovrebbe essere comprensibile senza codice insight, quindi per me sarebbe un suggerimento che si sta utilizzando di errore errato meccanismo di reporting in questa situazione.
    • Perché è un sintomo di errore errato meccanismo di segnalazione? È più facile trovare l’errore se si dispone di una migliore conoscenza prima di guardare il codice, non è vero?
    • Perché, per me, è un suggerimento che il messaggio di potrebbe non essere un programmatore di fissaggio codice, ma per l’utente di un’applicazione che non dovrebbe mai essere fatto con assert.
    • Sono d’accordo al 100% che assert è una cattiva idea di raccontare qualcosa all’utente! Ma, io non sono convinto per il vostro parere, posso immaginare una situazione del genere quando assert non riesce a causa di dati errati da parte di un’altra funzione (naturalmente io’dont media funzione da un’altra classe o di modulo, voglio dire, ad esempio. un’altra funzione privata della stessa classe). Poi, una affermazione con messaggio significativo rende programmatore in grado di andare direttamente alla radice del problema (un’altra funzione), invece di cercare assert codice, e quindi di andare alla radice del problema.

  8. -6

    Per vc, aggiungere il codice riportato di seguito nell’affermare.h,

    #define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )
    • Modifica il tuo compilatore, intestazioni, è una cattiva idea.

Lascia un commento