Ich verwende ein Unit-Test-Framework, das sich auf eine REQUIRE
Makro zur Durchführung von Assertions.
Vereinfacht ausgedrückt funktioniert das Makro wie folgt:
#define REQUIRE( expr ) INTERNAL_REQUIRE( expr, "REQUIRE" )
Die Definition ist ähnlich wie diese:
#define INTERNAL_REQUIRE( expr, macroName ) \
PerformAssertion( macroName, #expr, expr );
PerformAssertion
sind die ersten beiden Parameter vom Typ: const char*
. Der Grund für den zweiten Parameter ( #expr
) ist, damit der genaue Ausdruck, der geltend gemacht wurde, protokolliert werden kann. Genau hier liegt das Problem. Der Präprozessor expandiert den Ausdruck, bevor er als const char *
Es handelt sich also nicht um denselben Ausdruck, der ursprünglich behauptet wurde.
Zum Beispiel:
REQUIRE( foo != NULL );
würde zu diesem Anruf führen:
PerformAssertion( "REQUIRE", "foo != 0", foo != 0 );
Wie Sie sehen können, wird der Ausdruck teilweise expandiert, z. B. der Ausdruck foo != NULL
erscheint im Protokoll als foo != 0
. Die NULL
(das ist ein Makro, das so definiert ist, dass es 0
) wurde vom C-Präprozessor erweitert, bevor der Nachrichtentext der Assertions erstellt wurde. Gibt es eine Möglichkeit, die Erweiterung für den Meldungstext zu ignorieren oder zu umgehen?
EDIT: Hier ist die Lösung, für alle, die es interessiert:
#define REQUIRE( expr ) INTERNAL_REQUIRE( expr, #expr, "REQUIRE" )
#define INTERNAL_REQUIRE( expr, exprString, macroName ) \
PerformAssertion( macroName, exprString, expr );