Home > Software design >  MISRA warning when overriding bitwise operator
MISRA warning when overriding bitwise operator

Time:12-28

I wrote a simple wrapper for the logging interface, so I can use left-shift operator<< to print log.

logger_wrapper.h

class LoggerWrapper
{
public:

    LoggerWrapper(logging::LoggerInterface *logger, logging::LogPriority priority);

    ~LoggerWrapper();

    bool log_enabled();

    std::stringstream& get_stream();

private:

    std::stringstream stream_;

    logging::LoggerInterface *logger_;

    logging::LogPriority priority_;
};


template <typename T>
LoggerWrapper& operator<<(LoggerWrapper& record, T&& t) {
    if (record.log_enabled())
    {
        record.get_stream() << std::forward<T>(t);
    }
    return record;
}

template <typename T>
LoggerWrapper& operator<<(LoggerWrapper&& record, T&& t)
{
    return record << std::forward<T>(t);
}

logger_wrapper.cpp

#include "logger_wrapper.h"


LoggerWrapper::LoggerWrapper(logging::LoggerInterface *logger, logging::LogPriority priority)
    : logger_{ logger }
    , priority_ { priority }
{

}

bool LoggerWrapper::log_enabled()
{
    return (nullptr != logger_) && (logger_->isLogPriorityEnable(priority_));
}

std::stringstream& LoggerWrapper::get_stream()
{
    return stream_;
}

LoggerWrapper::~LoggerWrapper()
{
    if (log_enabled())
    {
        logger_->log(priority_, stream_.str());
    }
}

The code was compiled successfully, but I had some MISRA warning:

M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<basic_string&>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<basic_string<char,char_traits<char>,allocator<char>>>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<const atomic&>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<const basic_string&>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<const char (&)[10]>())
...

According to MISRA C 2008, Rule M-5-17-1 states that:

The semantic equivalence between a binary operator and its assignment operator form shall be preserved.

I hope someone can explain me what the warnings mean and what I should do to remove it. Any reply is greatly appreciated. Thank you.

CodePudding user response:

The MISRA guideline essentially says that "For any binary operator (call it @), if you overload operator@() for your class then also overload the operator@=(), and ensure they behave consistently". The purpose is to ensure that (where x is an instance of your class).

 x = x @ y;    //  @ may represent  , - , <<, *, /, .....

has the same net effect as (i.e. is consistent with).

x @= y;

In your case, your class has (templated) overloads of operator<<() but no corresponding overloads of operator<<=().

One way to stop the warnings is to provide corresponding overloads of operator<<=() whenever you provide an operator<<() (or vice versa).

For example, provide a operator<<=()

template <typename T>
LoggerWrapper& operator<<=(LoggerWrapper& record, T&& t)
{
    if (record.log_enabled())
    {
        record.get_stream() << std::forward<T>(t);
    }
    return record;
}

and (to ensure the required consistency), use the approach of defining the operator<<() so it calls the operator<<=().

template <typename T>
LoggerWrapper& operator<<(LoggerWrapper& record, T&& t)
{
     return operator<<=(record, t);
} 
  • Related