Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Это правило актуально только для C.
Оператор sizeof
возвращает размер указателя, а не массива, для случаев, когда массив был передан в функцию по копии.
Рассмотрим фрагмент кода:
char A[100];
void Foo(char B[100])
{
}
В этом коде объект A
является массивом, и выражение sizeof(A)
вернет значение 100
.
Объект B
, несмотря на то, как он задекларирован, является обычным указателем. Значение 100
в квадратных скобках является лишь подсказкой программисту, что передаваемый массив должен содержать сто элементов. Таким образом, выражение sizeof(B)
будет равно размеру указателя, а размер последнего определяется реализацией (implementation-defined). Например, для 32-битных систем его размер равен 4 байтам, а для 64-битных систем — 8 байтам.
Предупреждение выдается в том случае, когда вычисляется размер указателя, переданного в качестве аргумента в формате имя_типа имя_массива[N]
. Такой код с высокой вероятностью содержит ошибку. Рассмотрим пример:
void Foo(float array[3])
{
const size_t n = sizeof(array) / sizeof(array[0]);
for (size_t i = 0; i < n; ++i)
array[i] = 0.0f;
}
Выражение sizeof(array) / sizeof(array[0])
неверно вычислит размер массива, из-за чего он не будет полностью заполнен значением 1.0f
.
Для предотвращения подобных ошибок необходимо явно передавать количество элементов в массиве.
Корректный код:
void Foo(float *array, size_t count)
{
for (size_t i = 0; i < count; ++i)
array[i] = 1.0f;
}
Данная диагностика классифицируется как:
|