risorse | good unit tests
Questa breve parte (la nona; qui la prima, qui la seconda, qui la terza, qui la quarta, qui la quinta, qui la sesta, qui la settima e qui l'ottava) è dedicata al supporto dell'oggetto nullptr.
L'infrastruttura non consente ancora il confronto tra puntatori e nullptr:
... CHECK(&obj == nullptr); // does not compile! ...
Per abilitare questo tipo di comparazioni è sufficiente specializzare l'espressione binaria, nelle due varianti – nullptr a destra e a sinitra:
template<Operator op, typename T> bool compare(T* lhs, std::nullptr_t rhs) { return ExprFactory<T*, std::nullptr_t, op>::logAndEvaluate(lhs, rhs); } template<Operator op, typename T> bool compare(std::nullptr_t lhs, T* rhs) { return ExprFactory<std::nullptr_t, T*, op>::logAndEvaluate(lhs, rhs); }
Poiché non è possibile serializzare l'oggetto nullptr in uno stream, è necessario prevedere un operatore di conversione a stringa:
std::string toString(std::nullptr_t) { return "<nullptr>"; }
Il programma di test diventa:
... CHECK(NULL == cpi1); //~ assert(lastFailure == "[error] NULL == cpi1 evaluates to 0 == 0012FF24"); // nullptr CHECK(pi1 == nullptr); //~ assert(lastFailure == "[error] pi1 == nullptr evaluates to 0012FF24 == <nullptr>"); CHECK(&i1 == nullptr); //~ assert(lastFailure == "[error] &i1 == nullptr evaluates to 0012FF24 == <nullptr>"); int* pnullptr = nullptr; CHECK(pnullptr != NULL); //~ assert(lastFailure == "[error] pnullptr != NULL evaluates to 00000000 != 00000000"); CHECK(pnullptr != 0); //~ assert(lastFailure == "[error] pnullptr != 0 evaluates to 00000000 != 00000000"); CHECK(cpi1 == nullptr); //~ assert(lastFailure == "[error] cpi1 == nullptr evaluates to 0012FF24 == <nullptr>"); CHECK(nullptr == &i1); //~ assert(lastFailure == "[error] nullptr == &i1 evaluates to <nullptr> == 0012FF24"); CHECK(0 != pnullptr); //~ assert(lastFailure == "[error] 0 != pnullptr evaluates to 00000000 != 00000000"); CHECK(NULL != pnullptr); //~ assert(lastFailure == "[error] NULL != pnullptr evaluates to 00000000 != 00000000"); CHECK(nullptr == cpi1); //~ assert(lastFailure == "[error] nullptr == cpi1 evaluates to <nullptr> == 0012FF24"); // objects Object o1(1); Object o2(2); ...
Al solito, trattandosi di puntatori, le assert sono commentate, perché i valori da essi assunti non sono stabili e la loro rappresentazione dipende dal compilatore.
Aggiornamento [05/02/2014]: sempre a proposito di puntatori, la versione 4.8.2 di MinGW emette il warning «ISO C++ forbids comparison between pointer and integer» in corrispondenza dei confronti tra puntatori e costante NULL; sebbene l'uso di tale costante sia deprecata, per eliminare il messaggio basta fornire un'ulteriore specializzazione del metodo compare:
template<Operator op, typename T> bool compare(T* lhs, long long rhs) { return ExprFactory<T*, T*, op>::logAndEvaluate(lhs, reinterpret_cast<T*>(rhs)); } template<Operator op, typename T> bool compare(long long lhs, T* rhs) { return ExprFactory<T*, T*, op>::logAndEvaluate(reinterpret_cast<T*>(lhs), rhs); }
Pagina modificata il 04/02/2014