Как использовать #degine guard-in-stati c удобный для анализа кода код? - PullRequest
0 голосов
/ 13 февраля 2020

В настоящее время мы используем #ifdef DEPLOYED для идентификации развернутых сборок нашего проекта c ++ 17 и изменения поведения.

Однако, stati c анализ кода, например, часто внутри IDE (и на на первый взгляд справедливо) предупреждает о неиспользуемых переменных, которые в прошлом я опрометчиво удалял, чтобы потом позже выяснить в нашей ночной, что сборка развертывания не удалась (потому что в нашем CI тестирование выполняется на сборках без развертывания, только ночное развертывание сборки с включенным флагом).

Один из многих примеров:

catch (std::exception& e) {
#if defined(DEPLOYED)
    std::cerr << "Exception doing something " << e.what() << std::endl;
#else
    throw;
#endif
}

На компьютере разработчика e никогда не использовался, поэтому возникло предупреждение, catch (std::exception& e) { был изменен на catch (std::exception&) {, поэтому не удалось развернуть сборки.

Как это могло быть написано по-другому? Одно решение, которое я имел в виду, выглядит следующим образом, но это очень громоздко, и мне интересно, можно ли это сделать более элегантно:

catch (std::exception& e) {
    if (
#if defined(DEPLOYED)
       true
#else
       false
#endif
    ) {
        std::cerr << "Exception doing something " << e.what() << std::endl;
    } else {
        throw;
    }
#endif
}

Другой пример включает переименование переменной , которое было сделано везде (Поддерживается IDE "заменить все вхождения), кроме блоков кода #if defined(DEPLOYED).

  • Не модно ли обрабатывать сборки dev и deploy в C ++ с define? Если да, то что рекомендуемый способ?
  • Особенно, когда не развернутый код может содержать вычислительно дорогие вызовы, как мне убедиться, что они не появляются в сборках развертывания - может быть, даже могут быть полностью оптимизированы?

Ответы [ 3 ]

1 голос
/ 13 февраля 2020

Разве не модно обрабатывать сборки dev и deploy в C ++ с define?

Не совсем, но не рекомендуется разбрасывать #ifdef s в твой бизнес логи c. Лучше реорганизовать части, которые изменяются между режимами сборки, в отдельные функции и предоставлять различные реализации этих функций в зависимости от активного режима сборки.

Как это можно написать по-разному?

Атрибут [[maybe_unused]] решает эту проблему элегантно.

catch ([[maybe_unused]] std::exception& e) {
#if defined(DEPLOYED)
    std::cerr << "Exception doing something " << e.what() << std::endl;
#else
    throw;
#endif
}
0 голосов
/ 13 февраля 2020

Некоторые анализаторы состояния c (в частности, Frama- C и, вероятно, Clang stati c анализатор ) обрабатывают предварительно обработанную форму C ++. Вы можете рассмотреть возможность их использования в командной строке (и запустить их из вашего средства автоматизации сборки , например, из вашего Makefile)

И вы также можете (с несколькими недели или месяцы работы) код вашего G CC плагина , чтобы взаимодействовать с вашим любимым анализатором или помощником по анализу stati c. Для вдохновения загляните в Bismon .

0 голосов
/ 13 февраля 2020

Не модно ли использовать сборки dev и deploy в C ++ с define? Если да, то каков рекомендуемый способ?

Вероятно, было бы лучше управлять этим с помощью системы сборки. Затем система сборки может извлекать правильные файлы / методы в зависимости от того, является ли ее развертывание или отладочная сборка

Ваш код может выглядеть примерно так:

catch (std::exception& e) 
{
    HandleError(e); 
}

, где HandleError в развертывании сборка только журналов, но в отладке перебрасывает е.

Особенно, когда не развернутый код может содержать вычислительно дорогие вызовы, как я могу убедиться, что они не появляются в сборках развертывания - может быть, даже может быть полностью оптимизирован?

Это гарантируется при использовании системы сборки, поскольку нежелательные файлы никогда не будут скомпилированы

...