1

I'm using this function to copy some values from one array to other array:

void *copy_array(const void *src, void *dest, uint8 pos, uint8 len, uint8 elemsize)
{
   const unsigned char *csrc = src;

   memcpy(dest, csrc + (pos * elemsize), len * elemsize);
}

Is there any similar way to do this without using pointer arithmetic? MISRA suggests to avoid pointer arithmetic.

13
  • 3
    There is no good reason to avoid pointer arithmetic in this code if it is to be used in production software. Is this an exercise for a class? If so, what is the actual problem statement? There are different conceptual levels on which “pointer arithmetic” can be considered to be taking place—an explicit expression in C source code, an implicit expression such as an array reference, and at the machine level. At the latter level, it is impossible to avoid pointer arithmetic, since the memory address is needed to load the data and therefore it must be calculated. What is the real problem? Commented Mar 25, 2020 at 15:58
  • 2
    The answer depends on the level of "similarity" you require ;-) If you need misra compliance I'd recommend avoiding anything accepting or returning void* if possible. Commented Mar 25, 2020 at 16:03
  • 3
    IMO the main problem here is having void pointers in the first place. Commented Mar 25, 2020 at 16:15
  • 2
    C code can't be type safe AND generic, so you have to choose one - and if you need MISRA compliance, the choice is not yours - the sad answer is, you can't implement this helper function in a safe way. Commented Mar 25, 2020 at 16:19
  • 4
    Basically, the MISRA rules do not want you screwing around with pointer arithmetic because you might muck it up. But this routine is passed only addresses, element sizes, and element indices. That means it cannot do its work without calculating addresses (directly or indirectly), and anybody who calls it has already run the risk MISRA wants to avoid, by decomposing their high-level objects (such as an array of known type) into pieces such as element sizes. About the best you might do in this routine is const uint8 (*x)[elemsize] = src; memcpy(dest, &x[pos], len * sizeof *x);. Commented Mar 25, 2020 at 17:00

1 Answer 1

1

For MISRA compliance, simply do memcpy(dest, &csrc[pos * elemsize], len * elemsize);.

Though I don't quite understand why you need a function for this, instead of just calling memcpy directly. As mentioned in comments, MISRA frowns at the use of void pointers through advisory rules, since mission-critical software should be deterministic, not generic.

Also, len * elemsize is rather questionable, since this would limit the function to arrays of maximum 255 bytes.

You could potentially avoid a lot of MISRA problems by converting the function to a function-like macro. Not necessarily an improvement readability-wise, but as far as I remember this should be MISRA compliant:

#define copy_array(src, dst, pos, len, elemsize) \
  memcpy((dst), &(src)[(pos)*(elemsize)], (len)*(elemsize))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.