V2577. MISRA. The function argument corresponding to a parameter declared to have an array type should have an appropriate number of elements.
This diagnostic rule is based on the software development guidelines developed by MISRA (Motor Industry Software Reliability Association).
This diagnostic rule is only relevant to C. Suppose a formal function parameter was declared as an array with a fixed size. The array is passed as an actual argument. Its size must not be smaller than the array received by the function.
In C, one can pass an array to a function via passing a pointer to its beginning. Therefore, one can pass an array of any size to such a function. However, the function interface becomes less comprehensive when a formal parameter is a pointer. It is not clear whether the function works with a single element or with an array.
To indicate that a function works with a certain number of elements, declare the relevant parameter as an array. A macro is often used to specify the array size. The macro is then used to traverse the array elements:
#define ARRAY_SIZE 32
void foo(int arr[ARRAY_SIZE])
{
for (size_t i = 0; i < ARRAY_SIZE; ++i)
{
// Do something with elements
}
}
Keep in mind that such an array is still a pointer. Hence, one can pass an array with fewer elements. This can lead to the array index out of bounds, which is undefined behavior:
#define ARRAY_SIZE 32
void foo(int arr[ARRAY_SIZE]);
void bar()
{
int array1[32] = { 1, ...., 32 };
int array2[28] = { 1, ...., 28 };
foo(array2); // <=
}
In this example, the function received an array of a wrong size. The correct option may be:
#define ARRAY_SIZE 32
void foo(int arr[ARRAY_SIZE]);
void bar()
{
int array1[32] = { 1, ...., 32 };
int array2[28] = { 1, ...., 28 };
foo(array1); // <=
}
Another option is to change the number of elements of the array passed to the function and fill in the added elements with default values:
#define ARRAY_SIZE 32
void foo(int arr[ARRAY_SIZE]);
void bar()
{
int array1[32] = { 1, ...., 32 };
int array2[32] = { 1, ...., 28 }; // <=
foo(array2);
}
If the function processes arrays of different sizes, the rule allows you to use an array of any size as an argument to the function. The array size should be passed in a different way, such as this:
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
void foo(int arr[], size_t count);
void bar()
{
int array1[] = { 1, 2, 3, 4, 5 };
int array2[] = { 10, 20, 30 };
foo(array1, ARRAY_SIZE(array1));
foo(array2, ARRAY_SIZE(array2));
}
This diagnostic is classified as:
|