#c #misra #log4cplus
#c #misra #log4cplus
Вопрос:
Я использую log4cplus
, и мой misra-проверяет наличие чего-то столь же невинного, как
LOG4CPLUS_INFO(
logger,
std::string("ABC") std::string("DEF"));
выход (среди прочего) The underlying type of `0L` is implicitly reduced from `8-bit signed char` to {code{bool}}.
. Это происходит также, когда я помещаю соответствующие литералы, а не помещаю их внутрь string
. Интересно, как это исправить. Или, в более общем смысле, как бы вы объединили несколько сообщений журнала и при этом сохранили MISRA-проверки счастливыми?
Комментарии:
1. MISRA позволяет использовать объединение двух строк. Я не знаком с log4cplus, но это может быть вызов макроса, который не нравится MISRA. В качестве альтернативы, если он не жалуется на одно сообщение, просто создайте строку заранее и передайте объединенную строку.
2. Этот макрос, похоже, не попадает ни в одну из одобренных MISRA категорий вариантов использования: «Макросы C должны использоваться только для защиты включения, определителей типов или спецификаторов классов хранения».
3. @user7860670 Динамическая память также не должна использоваться и
std::string
использует это, есть много вещей, которые она не допускает4. Действительно… почему вы используете std::string в приложении MISRA? Не говоря уже об этом зловещем функциональном макросе.
Ответ №1:
Я взглянул на LOG4CPLUS_INFO
и это макрос, определенный как:
#if !defined(LOG4CPLUS_DISABLE_INFO)
#define LOG4CPLUS_INFO(logger, logEvent)
LOG4CPLUS_MACRO_BODY (logger, logEvent, INFO_LOG_LEVEL)
и LOG4CPLUS_MACRO_BODY
определяется как:
#define LOG4CPLUS_MACRO_BODY(logger, logEvent, logLevel)
LOG4CPLUS_SUPPRESS_DOWHILE_WARNING()
do {
log4cplus::Logger const amp; _l
= log4cplus::detail::macros_get_logger (logger);
if (LOG4CPLUS_MACRO_LOGLEVEL_PRED (
_l.isEnabledFor (log4cplus::logLevel), logLevel)) {
LOG4CPLUS_MACRO_INSTANTIATE_OSTRINGSTREAM (_log4cplus_buf);
_log4cplus_buf << logEvent;
log4cplus::detail::macro_forced_log (_l,
log4cplus::logLevel, _log4cplus_buf.str(),
__FILE__, __LINE__, LOG4CPLUS_MACRO_FUNCTION ());
}
} while (0)
LOG4CPLUS_RESTORE_DOWHILE_WARNING()
и поэтому ваш MISRA checker будет проверять вызов макроса. И МИСРА любит if
, чтобы утверждения были определены явно в терминах bool
, например, а не if(node)
как ему нравится if(node!=nullptr)
, и я думаю, что у него может быть проблема с последней строкой:
} while (0)
As 0
неявно преобразуется в bool
. Вы должны посмотреть, получите ли вы такое же предупреждение, добавив простой do{}while(0);
цикл в свой код и снова запустив средство проверки.
И если вам нужен безопасный способ ведения журнала MISRA, я бы избегал использования макросов. Вы можете создать простой класс ведения журнала с помощью a std::ofstream
и a std::mutex
и сохранить его в области пространства имен, определенной как extern в вашем заголовочном файле.
Комментарии:
1. Правда, я также обнаружил это, изучив исходный код библиотеки log4cplus…
2. Позвольте мне добавить, что макросы log4cplus предназначены только для удобства. Вы можете реализовать любые средства ведения журнала, которые вы хотите, с помощью методов API без каких-либо макросов.