Home > Blockchain >  Can anybody provide a MISRA C compliant 'offsetof' macro/template/function that works wi
Can anybody provide a MISRA C compliant 'offsetof' macro/template/function that works wi

Time:04-21

I'm trying to write defensive code and put static_assert<> to ensure a structure's member has a specific offset to satisfy some hardware requirements

MISRA C Rule 18-2-1 says "The macro offsetof shall not be used", so we've 'undef'd offsetof.

We've provided some template things, but they all fail when used in static_assert<>

I've been unable to find something that works with C 11 static_assert<> across compilers.

struct Commands
{
    uint32_t command[4];
};

struct DMA_Bundle
{
    struct header_
    {
        uint32_t num_of_elems;
        uint8_t reserved[60];
    } header;
    Commands array[16];
};

I'm trying to assure that array is 64 bytes from the beginning.

static_assert(offsetof(DMA_Bundle,array)==64,"zoinks");

Does works, but MISRA says but I can't use that. (and I can't argue with our functional safety people :/)

I've tried the following, and generally they don't work:

static_assert(offsetofarray()==64,"bar");
static_assert(myoffsetof(DMA_Bundle::array)==64,"double_zoinks");

The explicit offsetofarray() constexpr function does work under GCC 7.5.0, but it fails under later GCC and Clang (which is what our embedded processor tools use). It fails with 'non constant condition for static_assert'.

The other seems to complain of "invalid use of non-static data member 'DMA_Bundle::array'"

And, for what it's worth, I'm limited to C 11.

CodePudding user response:

Some background:

And, for what it's worth, I'm limited to C 11

And here is your first problem...

MISRA C :2008 only allows the use of C :2003 - anything after this is out of scope.

MISRA C Rule 18-2-1 says "The macro offsetof shall not be used", so we've 'undef'd offsetof.

Use of #undef is a violation of required Rule 16-0-3 (and it is unnecessary to #undef offsetof)


Now to address the main point:

Rule 18-2-1 is a required Rule which seeks to protect against undefined behaviour when the types of the operands are incompatible.

Does works, but MISRA says but I can't use that. (and I can't argue with our functional safety people :/)

The problem with many clip-board monitors is they can tick boxes, but adopt a "MISRA says no" attitude without understanding what MISRA actually says...

My suggestion, especially if only being used when associated with static_assert() is to raise a deviation (see section 4.3.2 and the extended guidance in MISRA Compliance).

A deviation is a perfectly legitimate approach, where a Rule may be causing an inconvenience, but the undefined behaviour is not applicable.

See profile for affiliation

  • Related