Я использую среду модульного тестирования, которая опирается на макрос REQUIRE
для выполнение утверждений.
Упрощенно, макрос работает следующим образом:
#define REQUIRE( expr ) INTERNAL_REQUIRE( expr, "REQUIRE" )
Который определяется примерно так:
#define INTERNAL_REQUIRE( expr, macroName ) \
PerformAssertion( macroName, #expr, expr );
Первые два параметра PerformAssertion
имеют тип: const char*
. Причина для второго параметра ( #expr
) заключается в том, что точное выражение, которое было утверждено, может быть зарегистрировано. Вот в чем проблема. Препроцессор расширяет выражение до того, как оно будет передано как const char *
, поэтому это не то же самое выражение, которое было изначально утверждено.
Например:
REQUIRE( foo != NULL );
Приведет к такому вызову:
PerformAssertion( "REQUIRE", "foo != 0", foo != 0 );
Как видите, выражение частично расширено, т.е. выражение foo != NULL
отображается в журнале как foo != 0
. NULL
(который является макросом, определенным как 0
) был расширен препроцессором C перед построением текста сообщения утверждений. Есть ли способ игнорировать или обойти расширение текста сообщения?
РЕДАКТИРОВАТЬ: Вот решение для всех любопытных:
#define REQUIRE( expr ) INTERNAL_REQUIRE( expr, #expr, "REQUIRE" )
#define INTERNAL_REQUIRE( expr, exprString, macroName ) \
PerformAssertion( macroName, exprString, expr );