Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement the CRTP following MISRA C++

My team is developing a embedded system where we need to follow MISRA C++.

We are refactoring the code to use less virtual methods so we are trying to implement the CRTP to use static polymorphism instead of the dynamic one.

But we have the problem that static polymorfism requires a pointer conversion, so our static analysis checker complains.

Here is the interface

template <typename T>
class UpdateMethod
{
protected:
    ~UpdateMethod() {}
 public:
    void operator()() const
    {
        // [MISRA Rule 5-2-7] violation:
        static_cast<const T*>(this)->update();
    }
};

Here is one of the implementations:

class A
    : public UpdateMethod<A>
{
 public:
    void update() const {}
};

When in pass the MISRA checker it complains about the static_cast (conversion from ptr to ptr (e926).

So, my question is: is there any good way to implement the CRTP without having to suppress the MISRA warning, so in a secured way?

A related question only about the pointer conversion: MISRA C++ 2008 Rule 5-2-7 violation: An object with pointer type shall not be converted to an unrelated pointer type, either directly or indirectly I have the same error in the CRTP.

Edit: As mentioned only C++03 and no external library like boost.

like image 526
LeDYoM Avatar asked Oct 11 '18 08:10

LeDYoM


2 Answers

You might use the reverse approach:

template <typename T>
class UpdateMethod : public T
{
 public:
    void operator()() const
    {
        this->update();
    }
};

class A_impl
{
 public:
    void update() const {}
};

typedef UpdateMethod<A_impl> A;
like image 55
Jarod42 Avatar answered Sep 30 '22 22:09

Jarod42


Ok problem is that tool does checking on template definition and not on template instantiation.

There must be some way to help tool understand the situation. The best way would be C++2a concepts, but most probably tool doesn't support that and compiler probably doesn't do that too.

Other solution would be provide a static_assert hoping that tool will understand that:

template <typename T>
class UpdateMethod
{
    static_assert(std::is_base_of<UpdateMethod<T>, T>::value, "This is CRTP");
protected:
    ~UpdateMethod() {}
 public:
    void operator()() const
    {
        static_cast<const T*>(this)->update();
    }
};

The other way is to use SFINAE and make operator available when casting make seance:

template <typename T>
class UpdateMethod
{
protected:
    ~UpdateMethod() {}
public:

    typename std::enable_if<std::is_base_of<UpdateMethod<T>, T>::value>::type
    operator()() const
    {
        static_cast<const T*>(this)->update();
    }
};

Or use both.

Try this I hope tool will understand that and stop reporting an error. If not then IMHO it is a bug in tool.

Somebody point out that that C++03 must be used. In this case you can use boost, where this helper templates enable_if and is_base_of where initially defined.

like image 32
Marek R Avatar answered Oct 01 '22 00:10

Marek R