равно — C ++ CPPUNIT_ASSERT с двумя параметрами

В некотором коде я нашел следующую строку:

CPPUNIT_ASSERT(1, val.getBytefield().size());

Действительно ли это сравнивает два параметра на равенство? Обычно я ожидаю, что это сравнение с CPPUNIT_ASSERT_EQUAL:

CPPUNIT_ASSERT_EQUAL(1, val.getBytefield().size());

Тест компилируется, и утверждение работает в случае 1, но не в случае 2. В чем разница?

1

Решение

Для меня это выглядит как неработающий код, возможно, в результате какого-то рефакторинга или другого редактирования, которое было сделано.

CPPUNIT_ASSERT макрос принимает один аргумент — выражение условия и утверждает, что это условие истинно (то есть, не удается, если это ложь).

Этот код пытается передать два аргумента, но вместо того, чтобы функционировать здесь как разделитель аргументов, запятая фактически работает как (немного неясная) оператор запятой. Оператор запятой оценивает свой первый операнд, отбрасывает результат, а затем вычисляет результат второго операнда. Поэтому начальный 1 это не имеет никакого отношения не-оп. Код эквивалентен:

CPPUNIT_ASSERT(val.getBytefield().size());

это означает, что он утверждает, что поле байта имеет ненулевой размер.

Очевидно, это отличается от вашего второго фрагмента кода:

CPPUNIT_ASSERT_EQUAL(1, val.getBytefield().size());

который утверждает, что размер байтового поля именно так равен 1.

1

Другие решения

Кажется, что вы используете компилятор имеет расширение, которое принимает 2 параметра в макросе с одним аргументом. Я думаю, это MSVC, видите этот

Следовательно, макрос проверит, является ли первый аргумент истинным или нет, в вашем случае это 1, который контекстуально преобразуется в bool значение true, от это расширение

#define CPPUNIT_ASSERT(C) \
( CPPUNIT_NS::Asserter::failIf( !(C),                                   \
CPPUNIT_NS::Message( "assertion failed",         \
"Expression: " #C), \
CPPUNIT_SOURCELINE() ) )

Вы можете дважды проверить мое заявление по изменению:

CPPUNIT_ASSERT(1, val.getBytefield().size());

с:

CPPUNIT_ASSERT(1000, val.getBytefield().size());

CPPUNIT_ASSERT_EQUAL(1, val.getBytefield().size());

Из моего эксперимента .size() скорее всего вернет std::size_t, От значение CPPUNIT_ASSERT_EQUAL:

#define CPPUNIT_ASSERT_EQUAL(expected,actual) \
(assertEquals((expected),          \
(actual),                \
CPPUNIT_SOURCELINE(),    \
"" ) )

а также assertEquals:

template<class T>
void assertEquals   (   const T &   expected,
const T &   actual,
SourceLine  sourceLine,
const std::string &     message
)

Потому что тип 1 (int) и тип возврата .size() (std::size_t), то не может быть найдена соответствующая функция, компилятор не может скомпилировать ваш код.


Я думаю, что это решение:

CPPUNIT_ASSERT(1 == val.getBytefield().size());
CPPUNIT_ASSERT_EQUAL(std::size_t(1), val.getBytefield().size());
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector