字符串连接、log4cplus 和 MISRA 合规性

string concatenation, log4cplus, and MISRA compliance

我正在使用 log4cplus,我的 misra-checks 看起来像

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 检查正常?

我查看了 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 & _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 检查器将检查宏的调用。 MISRA 喜欢根据 bool 明确定义 if 语句,例如而不是 if(node) 它喜欢 if(node!=nullptr) 我认为最后一行可能有问题:

     } while (0)                                                         \

因为 0 被隐式转换为 bool。您应该通过向您的代码添加一个简单的 do{}while(0); 循环并再次 运行 您的检查器来查看是否收到相同的警告。


如果您想要一种 MISRA 安全的日志记录方式,我会避免使用宏。您可以使用 std::ofstreamstd::mutex 进行简单的日志记录 class 并将其保存在头文件中定义为 extern 的命名空间范围内。