Булева конкатенация не может быть скомпилирована - PullRequest
0 голосов
/ 03 мая 2018

У меня есть следующее простое выражение в моей Catch Testframework. В идеале тест должен выдавать предупреждение, если тест не пройден.

К сожалению, Catch не может скомпилировать следующий фрагмент кода:

#define CATCH_CONFIG_MAIN
#include "catch2.hpp"

TEST_CASE("Simple") {
    int a = 4;
    int b = 1;
    CHECK(a == 5 || b == 2);
}

Visual Studio 2015 выдает следующую ошибку:

error C2676: Binary operator "||": "const Catch::BinaryExpr<LhsT,const int &>" does not define this operator or a conversion for this operator of to suitable type

Я бы ожидал что-то вроде следующего:

4==5 || 1==2 => false || false => false

Возможно ли это с помощью Catch или мне нужно использовать дополнительные паразиты:

#define CATCH_CONFIG_MAIN
#include "catch2.hpp"

TEST_CASE("Simple") {
    int a = 4;
    int b = 1;
    CHECK((a == 5 || b == 2));
}

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Catch Classic используется, чтобы обеспечить несколько лучшую ошибку, так как это будет ошибка во время создания типа с именем что-то по линии CATCH_STATIC_ASSERT_EXPRESSION_TOO_COMPLEX_REWRITE_..., но, видимо, которые исчезли при перезаписи слоя захвата выражения.

В любом случае, простой ответ уже был предоставлен пользователем 463035818, приложите выражение в скобках. Я хочу расширить, почему выражения, содержащие операторы && или || не поддерживаются.

Есть три части, почему операторы && и || не поддерживаются, два из них практичны, а один философский.

1) Магия TMP, используемая для разложения выражения и его красивой печати не может должным образом эмулировать поведение коротких замыканий встроенных операторов. Это означает, что поведение таких выражений будет отличаться от ожидания пользователя.

2) Уже упоминавшаяся магия ТМП довольно дорогая в отношении время компиляции, хотя у нас есть специальные пути для унарных и двоичных выражения. Наличие общего пути для выражений с переменным числом вероятностей в конечном итоге слишком дорого.

3) Использование || в утверждении обычно является кодовым (тестовым) запахом. В разумный модульный тест, вы должны быть в состоянии выразить ожидаемый результат точно, и для случаев, когда это не так (например, итерация неупорядоченный набор), логично или все еще не является хорошим решением для инструмента.

Примечание 1: использование && (логическое и) в модульном тесте вполне разумно и на самом деле довольно просто переписать выражение, используя && для компиляции и еще короткого замыкания:

REQUIRE((expr1 && expr2 && expr3));

REQUIRE(expr1);
REQUIRE(expr2);
REQUIRE(expr3);

Примечание 2: Это началось как комментарий к другому ответу, но потом перешел допустимую длину, и я заметил, что сообщение об ошибке для Catch2 действительно плох, поэтому я открыл проблему .

0 голосов
/ 03 мая 2018

Если вы прочитаете документы , вы найдете раздел с текстом:

ПРОВЕРКА (a == 2 || b == 1); Это выражение слишком сложное из-за || оператор. Если вы хотите проверить, что одно из нескольких свойств удерживайте, вы можете поместить выражение в скобки (в отличие от &&, Разложение выражения на несколько CHECK невозможно).

Также обратите внимание, что ...

Я бы ожидал что-то вроде следующего:

4==5 || 1==2 => false || false => false

... ваши ожидания немного не соответствуют. || имеет короткое замыкание, что означает, что если первый операнд оценивается как false, второй не оценивается.

...