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:
- 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.
friend inline functions violates MISRA C 2012 Rule 8.10
No, they do not.
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.
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;
}