Search code examples
c++misraqa-c

Converting a pointer to X to an array of X


"Don't!" is the correct answer, but unfortunately it's not the one I need.

If I do:

size_t array_size = func_that_calc_array_size();
char *foo = new char[array_size];
if (array_size > 42)
    foo[42] = 'X';

This is all perfectly legal, but my MISRA C++ code checker gives an error 5-0-15 on the foo[42], which says that "Array indexing shall be the only form of pointer arithmetic". This question has actually been asked before, but the question and answer missed a critical issue, namely that the documentation further states:

Array indexing shall only be applied to objects defined as an array type.

If you look at the documentation (a suspiciously bootleg copy can be found by searching for "misra c++ 2008 pdf") it has an example similar to:

void my_fn(uint8_t *p1, uint8_t p2[])
{
    p1[5] = 0; // Non-compliant - p1 was not declared as array
    p2[5] = 0; // Compliant
}

So, basically the code-checking tool matches the declaration to the usage. Is there any possible way to convert the pointer to an array?


In our real example, we are using OpenCV's uchar *cv::Mat::ptr(), so we can't just reserve a large-enough array.


Solution

  • I think the root of the problem here is char *foo = new char[array_size];. A MISRA checker is arguably allowed to assume that this is not an array, because all dynamic memory allocation is banned.

    You could try to see if you get the same error when writing char array[10]={0}; char* foo = array; because then you can dismiss this as a false positive tool bug.

    The purpose and rationale of the rule is to ban the form *(x + i) instead of x[i]. Nothing else. The rule does not block the use of the [] on a pointer operand.

    Several MISRA rules are however in place to ensure that all pointer arithmetic is done with operands that point at the same array, to prevent undefined behavior.

    MISRA-C:2004 and MISRA-C++:2008 also had some weird, vague requirement that function parameters should be declared as char param[] rather than char* param, but since that was nonsensical, all this talk about array style indexing was removed in MISRA-C:2012.

    (In fact there's no such thing as "array style indexing" in C or C++, see Do pointers support "array style indexing"?)