C ++ - Почему мой оператор else в операторе if-else игнорируется? - PullRequest
0 голосов
/ 04 апреля 2019

Что ж, я натолкнулся на странную проблему.

С момента добавления библиотеки spdlog в мой проект и соответствующей корректировки всего вывода журнала все остальные блоки моих операторов if-else игнорируются.Вывод журнала был заменен процедурой поиска и замены с простым шаблоном регулярных выражений (от printf-style до fmtlib-style).

spdlog: https://github.com/gabime/spdlog

После некоторой отладки,Теперь я написал следующую очень простую тестовую функцию:

void dbg_test() {
    bool success = false;

    BOOST_ASSERT_MSG(!success, "Sanity check");

    // This works
    if (success) {
        LOG_ERROR("Successful");
    } else {
        LOG_ERROR("Unsuccessful"); // Log's written
    }

    // This doesn't work
    if (success)
        LOG_ERROR("Successful (w/o)");
    else
        LOG_ERROR("Unsuccessful (w/o)"); // Log's missing
}

В зависимости от значения «success» теперь происходит следующее (BOOST_ASSERT_MSG адаптируется соответственно): success == true, «Successful» и «Successful»(без) "записывается в журнал.Если success == false, написано «Unsuccessful», а «Unsuccessful (w / o)» нет.

Конечно, я также проверил ведение журнала и хотел завершить программу с помощью exit (0) вместо записижурналы, но этот код также не работал:

void dbg_test() {
    bool success = false;

    BOOST_ASSERT_MSG(!success, "Sanity check");

    // This works
    if (success) {
        LOG_ERROR("Successful");
    } else {
        exit(0);
    }

    // This doesn't work
    if (success)
        LOG_ERROR("Successful (w/o)");
    else
        exit(0);
}

Для компиляции и отладки я использую Microsoft Visual Studio Community 2017 (версия 15.5.0).Соответствующая папка проекта была создана с помощью CMake 3.13.4.

В чем может быть причина этого?


Редактировать

Определение макросадля LOG_ERROR:

#define LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__)

1 Ответ

5 голосов
/ 04 апреля 2019

Много причудливого кода, но они не могут получить правильный макрос.Это не макрос LOG_ERROR (я не смог найти это), но он иллюстрирует проблему

#define SPDLOG_LOGGER_CALL(logger, level, ...) \
    if (logger->should_log(level)) \
        logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)

должно быть

#define SPDLOG_LOGGER_CALL(logger, level, ...)  \
    do \
        if (logger->should_log(level)) \
            logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__) \
    while (false)

Трюк do ... while гарантирует, что выводмакрос можно использовать как простое утверждение.Это не относится к утверждению if, что исходный вывод макроса, который, как вы обнаружили, испортит любой оператор if ... else, в котором он находится.

Может быть, вы могли бы присоединиться к проекту и добавить это исправление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...