Search code examples
c++misra

friend inline functions violates MISRA C 2012 Rule 8.10


Let's say we have the code snippet

#include <stdint.h>

class T {
    int32_t a;
    friend void foo(T*p);
};

inline void foo(T*p) {
    p->a = 1;
}

MISRA C checker will complain

Type: MISRA C-2012 Declarations and Definitions (MISRA C-2012 Rule 8.10, Required) Triage unavailable. main.cpp:8:

  1. misra_c_2012_rule_8_10_violation: The inline function "foo(T *)" is not declared with a static scope.

But code like below is illegal

#include <stdint.h>

class T {
    int32_t a;
    friend static void foo(T*p); // error: storage class specifiers invalid in friend function declarations
};

static inline void foo(T*p) {
    p->a = 1;
}

How can we workaround it? Thank you.


Solution

  • friend inline functions violates MISRA C 2012 Rule 8.10

    No, they do not.

    1. As it says right in the name, MISRA C applies to C. Friend functions are a C++-specific feature addressing a C++-specific issue. C++ is not C, and MISRA C does not apply to it. Not once does MISRA C 2012 mention the C++ language.

      MISRA did release one set of C++ guidelines, MISRA C++ 2008, but it seems largely to have been abandoned. Whereas MISRA C received multiple amendments and technical corrigenda, and two revised editions (the latest retitled MISRA C2023), MISRA does not seem to have published any further work on C++ guidelines since 2008.

    2. The problem is not that a friend function is inline, but rather that an inline function is not static. That the function in question is a friend to some class is coincidental. And this particular rule is aimed squarely at the C version of inline functions, which have some important differences from C++ inline functions.

    I am uncertain how or why you are checking C++ code against MISRA C, but you should not. MISRA C overall is not appropriate for C++, and those parts that are applicable to C++ are in no way sufficient to meet MISRA's safety goals.

    How can we workaround it?

    Option 1: stop checking C++ code against rules devised for the C language.

    Option 2: make the function an ordinary external function instead of an inline function. If the inline version is presently defined in a header, then you would also need to move that definition to a regular source file:

    header.h

    #include <stdint.h>
    
    void foo(T *p);
    
    class T {
        int32_t a;
        friend void foo(T *p);
    };
    

    source.cpp

    #include "header.h"
    
    void foo(T *p) {
        p->a = 1;
    }