Ein Hack, den ich gesehen habe, ist die Verwendung des &&Operators. Da ein Zeiger "wahr" ist, wenn er nicht null ist, können Sie Folgendes tun, ohne die Bedingung zu ändern:
assert(a == b &&"A is not equal to B");
Da assertder Zustand angezeigt wird, der fehlgeschlagen ist, wird auch Ihre Nachricht angezeigt. Wenn es nicht ausreicht, können Sie Ihre eigene myAssertFunktion oder Ihr eigenes Makro schreiben , das alles anzeigt, was Sie wollen.
Eine andere Möglichkeit besteht darin, die Operanden umzukehren und den Kommaoperator zu verwenden. Sie benötigen zusätzliche Klammern, damit das Komma nicht als Trennzeichen zwischen den Argumenten behandelt wird:assert(("A must be equal to B", a == b));
Keith Thompson
3
Es wäre jedoch schön, die Werte von Variablen drucken zu können, wie in:assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
Frank
7
@Frank printfgibt einen Wert ungleich Null zurück, wenn etwas gedruckt wurde, sodass Sie so etwas tun können assert(a == b && printf("a (%i) is not equal to b (%i)", a, b)), obwohl Sie an diesem Punkt wahrscheinlich Ihren eigenen Assert-Wrapper schreiben sollten.
zneak
1
Schlechter Code! Ich verstehe das nicht! Wenn a == b falsch ist, sollte der and-Ausdruck ebenfalls falsch sein, und daher sollte die Zeichenfolge nicht ausgewertet werden.
Ragnarius
1
@TUIlover, so funktionieren C-String-Literale nicht; Sie sind Konstanten zur Kompilierungszeit und ihre Verwendung in diesem Zusammenhang ist trivial optimiert. Es fallen keine Laufzeitkosten an.
Zneak
45
Eine andere Möglichkeit besteht darin, die Operanden umzukehren und den Kommaoperator zu verwenden. Sie benötigen zusätzliche Klammern, damit das Komma nicht als Trennzeichen zwischen den Argumenten behandelt wird:
assert(("A must be equal to B", a == b));
(Dies wurde aus Gründen der besseren Sichtbarkeit aus den obigen Kommentaren kopiert.)
Dies ist ein großartiger Ansatz, mit einem winzigen Problem wird "Warnung: linker Operand des Kommaoperators hat keine Auswirkung" angezeigt, wenn in g ++ mit `-Wunused-value
v010dya
1
oder mit einem Makro: #ifndef m_assert #define m_assert (Ausdruck, msg) assert ((msg, Ausdruck)) #endif
Szymon Marczak
Mit einem Makro-Wrapper können Sie die gcc-Warnung vermeiden:#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Jander
25
Hier ist meine Version des Assert-Makros, das die Nachricht akzeptiert und alles klar ausdruckt:
Ich bin ein wenig verwirrt. Wird #Expr als Zeichenfolge für die direkte Substitution behandelt? Was ist der Unterschied zwischen #Expr und Expr?
Minh Tran
@MinhTran Nehmen wir an, dass Ihre Assert-Bedingung lautet x == y. Dann wird Expr erweitert if( !(x == y))und hier wird die Bedingung überprüft, und #Expr wird in ein Zeichenfolgenliteral erweitert "x == y", das wir dann in eine Fehlermeldung einfügen .
Eugene Magdalits
Leider verursacht diese Lösung aufgrund der Verwendung reservierter Bezeichner undefiniertes Verhalten.
Sie können das entweder direkt verwenden oder den Code von Boost kopieren. Beachten Sie auch, dass Boost Assert nur ein Header ist, sodass Sie nur diese einzelne Datei abrufen können, wenn Sie nicht den gesamten Boost installieren möchten.
"Da der Leser des Assert-Fehlers die Datei und die Zeile trotzdem aus der Fehlermeldung nachschlagen wird" - nur wenn sie fleißig sind.
Jason S
Nur wenn sie den Fehler beheben wollen, meinen Sie ... was für ein dummer Kommentar
Metamorphose
1
Nein. Je einfacher Sie es den Menschen machen, das Problem zu erkennen, desto wahrscheinlicher werden sie Maßnahmen ergreifen.
Jason S
Achselzucken Nicht einverstanden.
Metamorphose
2
assert ist eine Makro- / Funktionskombination. Sie können Ihre eigene Makro / Funktion, mit definieren __FILE__, __BASE_FILE__, __LINE__etc, mit Ihrer eigenen Funktion, nimmt eine benutzerdefinierte Nachricht
Antworten:
Ein Hack, den ich gesehen habe, ist die Verwendung des
&&
Operators. Da ein Zeiger "wahr" ist, wenn er nicht null ist, können Sie Folgendes tun, ohne die Bedingung zu ändern:Da
assert
der Zustand angezeigt wird, der fehlgeschlagen ist, wird auch Ihre Nachricht angezeigt. Wenn es nicht ausreicht, können Sie Ihre eigenemyAssert
Funktion oder Ihr eigenes Makro schreiben , das alles anzeigt, was Sie wollen.quelle
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
gibt einen Wert ungleich Null zurück, wenn etwas gedruckt wurde, sodass Sie so etwas tun könnenassert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, obwohl Sie an diesem Punkt wahrscheinlich Ihren eigenen Assert-Wrapper schreiben sollten.Eine andere Möglichkeit besteht darin, die Operanden umzukehren und den Kommaoperator zu verwenden. Sie benötigen zusätzliche Klammern, damit das Komma nicht als Trennzeichen zwischen den Argumenten behandelt wird:
(Dies wurde aus Gründen der besseren Sichtbarkeit aus den obigen Kommentaren kopiert.)
quelle
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Hier ist meine Version des Assert-Makros, das die Nachricht akzeptiert und alles klar ausdruckt:
Jetzt können Sie dies verwenden
Und im Fehlerfall erhalten Sie eine Meldung wie folgt:
Schön und sauber, zögern Sie nicht, es in Ihrem Code zu verwenden =)
quelle
x == y
. Dann wird Expr erweitertif( !(x == y))
und hier wird die Bedingung überprüft, und #Expr wird in ein Zeichenfolgenliteral erweitert"x == y"
, das wir dann in eine Fehlermeldung einfügen .http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Sie können das entweder direkt verwenden oder den Code von Boost kopieren. Beachten Sie auch, dass Boost Assert nur ein Header ist, sodass Sie nur diese einzelne Datei abrufen können, wenn Sie nicht den gesamten Boost installieren möchten.
quelle
Da die Antwort von zneak den Code etwas verwickelt, ist es besser, nur den Zeichenfolgentext zu kommentieren, über den Sie sprechen. dh:
Da der Leser des Assert-Fehlers die Datei und die Zeile ohnehin anhand der Fehlermeldung nachschlägt, wird hier die vollständige Erklärung angezeigt.
Denn am Ende des Tages ist dies:
liest sich besser als das:
in Bezug auf die menschliche Analyse von Code dh. Lesbarkeit. Auch kein Sprachhack.
quelle
assert ist eine Makro- / Funktionskombination. Sie können Ihre eigene Makro / Funktion, mit definieren
__FILE__
,__BASE_FILE__
,__LINE__
etc, mit Ihrer eigenen Funktion, nimmt eine benutzerdefinierte Nachrichtquelle
Fügen Sie für vc den folgenden Code in assert.h hinzu:
quelle