Passing buffers in C with MISRA compliance

2.5k views Asked by At

MISRA is frustrating our developers.

We are getting MISRA errors about "Do not apply pointer arithmetic to pointer" and "pointer does not point to array".

We are using the syntax of:

uint8_t const * p_buffer

to pass a buffer to a function that writes the buffer to a SPI bus.

Given an example code fragment:

static void Write_Byte_To_SPI_Bus(uint8_t byte);

void Write_Buffer_To_SPI_Bus(uint8_t const * p_buffer,
                             unsigned int quantity)
{
  for (unsigned int i = 0; i < quantity; ++i)
  {
    Write_Byte_To_SPI_Bus(*p_buffer++);
  }
}

Is there a way to have a pointer to a cell in an array and increment it that will satisfy MISRA?

My interpretation is MISRA wants to incrementing indices to the array and not a pointer:

void Write_Array_To_SPI_Bus(uint8_t const p_array[],
                            unsigned int quantity)
    {
      for (unsigned int i = 0; i < quantity; ++i)
      {
        Write_Byte_To_SPI_Bus(p_array[i]);
      }
    }

Many of the developers are old school and prefer to use pointers to uint8_t rather than passing an array.

3

There are 3 answers

0
Peter On BEST ANSWER

John Bode has already given a reply about how (in effect) your second code fragment addresses the MISRA guideline.

I'll address your question "Is there a way to have a pointer to a cell in an array and increment it that will satisfy MISRA?"

The short answer is "no". Rule 17.4 (in MISRA 2004 - I don't have the 2012 version handy) states "Array indexing shall be the only allowed form of pointer arithmetic". This is essentially the underpinning of the changes you are required to make in this case.

The longer answer is that the MISRA guidelines are based on a premise that array syntax is somehow safer than pointer dereferencing. My personal view is that this is a weakness in MISRA, since it doesn't address the problems of an array index going out of bounds - which actually has the same consequence of pointer arithmetic that passes beyond bounds of the array.

Also, the "old school" approach of shadowing a variable (using an index based loop, and incrementing the pointer in the loop) is not exactly good practice either. It has all the lack of safety that the MISRA guideline is trying to prevent, plus making the code harder to read (mere humans have to work harder to understand that there is a one-to-one relationship between the values of i and p_buffer - and code which is harder to understand is easier to get wrong).

2
John Bode On

Remember that as far as C is concerned,

void Write_Buffer_To_SPI_Bus(uint8_t const * p_buffer,
                             unsigned int quantity)

and

void Write_Array_To_SPI_Bus(uint8_t const p_array[],
                            unsigned int quantity)

mean exactly the same thing; in the context of a function parameter declaration, uint8_t const * p_buffer and uint8_t const p_array[] both declare pointer types, not a pointer and an array type.

Your second snippet should satisfy MISRA, and it's effectively the same as the first snippet.

1
Andrew On

MISRA is frustrating our developers.

To be specific, a rigid adherence to MISRA is frustrating your developers.

In the case that you have highlighted, a Deviation is an appropriate mechanism...