Korzystam z platformy testów jednostkowych, która polega na makrze REQUIRE
do wykonywania asercji.Niepożądane preprocesorowe wstępne przetwarzanie C
uproszczonej makro działa tak:
#define REQUIRE(expr) INTERNAL_REQUIRE(expr, "REQUIRE")
który jest zdefiniowany podobny do tego:
#define INTERNAL_REQUIRE(expr, macroName) \
PerformAssertion(macroName, #expr, expr);
PerformAssertion
„s Pierwsze dwa parametry są typu: const char*
. Powód drugiego parametru (#expr
) jest taki, że można potwierdzić dokładne wyrażenie, które zostało potwierdzone. Tutaj leży kwestia. Preprocesor rozszerza wyrażenie, zanim zostanie przekazane jako const char *
, więc nie jest to to samo wyrażenie, które zostało pierwotnie zadeklarowane.
Na przykład:
REQUIRE(foo != NULL);
spowodowałoby to wezwanie:
PerformAssertion("REQUIRE", "foo != 0", foo != 0);
Jak widać, wyrażenie jest częściowo rozwinięty, np wyrażenie foo != NULL
pojawia się w dzienniku jako foo != 0
. Obiekt NULL
(który jest makrem zdefiniowanym jako 0
) został rozwinięty przez preprocesor C przed utworzeniem tekstu wiadomości potwierdzenia. Czy istnieje sposób, w jaki mogę zignorować lub pominąć rozszerzenie tekstu wiadomości?
EDIT: Oto rozwiązanie dla każdego, ciekawy:
#define REQUIRE(expr) INTERNAL_REQUIRE(expr, #expr, "REQUIRE")
#define INTERNAL_REQUIRE(expr, exprString, macroName) \
PerformAssertion(macroName, exprString, expr);
Po prostu użyj 'INTERNAL_REQUIRE (expr, #expr," REQUIRE ")' zamiast formularza dwuargumentowego? – kennytm
Tak, to wystarczy. – Jeff