Таким образом, в doctest (моя среда тестирования) пользователь может отключить все тесты, определив DOCTEST_CONFIG_DISABLE, который создает следующий код и макросы:
TEST_CASE("name") {
int a = 5;
int b = 6;
CHECK(a == b);
}
превратиться в следующее после препроцессора:
template<typename T>
void some_anon_func_123() {
int a = 5;
int b = 6;
}
это означает, что саморегистрирующийся тестовый пример превращается в неэкземплярную функцию шаблона, а макрос CHECK()
(который функционирует как оператор if, проверяющий условие) в неоперативную функцию, например:
#define CHECK(x) ((void)0) // if disabled
Однако, если пользователь включил такой тестовый код в отдельную функцию, например:
static int g() {
std::cout << "called!" << std::endl;
return 42;
}
static void f() {
int a = 5;
CHECK(a == g());
}
TEST_CASE("name") {
f();
}
тогда будут предупреждения о неиспользуемых функциях и неиспользуемых переменных. doctest гордится созданием 0 предупреждений даже на самых агрессивных уровнях, так что это неприемлемо.
Я попытался использовать трюк ((void) ...)
, передав ему аргумент макроса следующим образом:
#define CHECK(x) ((void)(x))
и это действительно отключило предупреждения (по крайней мере, для a
и g()
), но для этого оператора все еще генерируется код - если я вызову функцию f()
из моего main()
, я увижу строку called!
, напечатанную в консоли. Это нежелательно, поскольку я хочу, чтобы компиляция была максимально быстрой, когда тестовые примеры и утверждения отключены в сборке (с помощью DOCTEST_CONFIG_DISABLE). Если у пользователя есть 100 000 утверждений и сборок с их отключением, ему не нужны все эти ненужные накладные расходы на создание кода и время компиляции для макросов, которые должны быть отключены (тот CHECK()
).
__attribute__((unused))
нужно использовать в месте объявления переменной - я не могу вставить его в макрос CHECK()
(или можно? не знаю...).
Не уверен, что _Pragma()
может помочь - и даже если бы мог - известно, что у него есть проблемы с GCC:
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id= 55578а>
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543
Есть ли решение моей проблемы - например, передача выражения в какой-то шаблон или что-то еще...? (необходимо решение C++98)
Я подробно объяснил свою проблему только потому, что меня часто обвиняют в проблеме XY. ..
ИЗМЕНИТЬ:
С решением C++11 тоже все в порядке - некоторые функции C++11 все равно начали условно проникать в библиотеку...