Nano Hash - криптовалюты, майнинг, программирование

молчание предупреждений о неиспользуемых переменных/функциях в момент их условно скомпилированного использования

Таким образом, в 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:

Есть ли решение моей проблемы - например, передача выражения в какой-то шаблон или что-то еще...? (необходимо решение C++98)

Я подробно объяснил свою проблему только потому, что меня часто обвиняют в проблеме XY. ..

ИЗМЕНИТЬ:

С решением C++11 тоже все в порядке - некоторые функции C++11 все равно начали условно проникать в библиотеку...


  • Как насчет того, чтобы просто использовать #define CHECK(x) вместо #define CHECK(x) ((void)0)? 05.04.2017
  • @Garf365 2 проблемы с этим - во-первых, не требуется точка с запятой после используемого макроса, а во-вторых - переменная a и функция g() по-прежнему не будут использоваться ... 05.04.2017
  • Это не мучительные подробности, это основная информация о том, что вы хотите сделать, что вы пробовали и почему это не удалось. И говоря о проблеме XY, почему бы вам просто не использовать #ifndef DOCTEST_CONFIG_DISABLE? 05.04.2017
  • @nwp действительно можно использовать, но я не могу просить пользователя сделать это. Я хочу, чтобы библиотека ощущалась как языковая функция — полностью прозрачная 05.04.2017

Ответы:


1

Итак, вы хотите «солгать» компилятору, что используете функцию, которую на самом деле не вызываете. Итак, как использовать фрагмент кода, не выполняя его?

Кажется, единственное, что работает на всех популярных компиляторах, — это решение только для С++ 11 — лямбда, которая никогда не вызывается:

#define CHECK(x) [&](){ ((void)(x)); }

Если вам абсолютно необходимо решение c++98, sizeof также будет работать на многих компиляторах, за исключением MSVC:

#define CHECK(x) sizeof(x)

MSVC по-прежнему будет предупреждать о невызванных функциях в выражении x.

Я думаю, для максимального охвата вы могли бы использовать комбинацию из двух.

05.04.2017
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..