V2586. MISRA. Flexible array members should not be declared.
Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Это правило актуально только для C. Не рекомендуется определять структуры, содержащие flexible-массив. Такие структуры применяются, если предполагается динамически выделять под них память, и при этом размер хранимых данных заранее неизвестен.
Пример:
typedef struct
{
size_t len;
int data[]; // flexible array
} S;
S* alloc_flexible_array(size_t n)
{
S *obj = malloc(sizeof(S) + (n * sizeof(int)));
obj->len = n;
return obj;
}
При таком объявлении структуры для массива 'data' размер будет определяться во время выполнения в зависимости от фактического объема данных.
Опасность таких структур состоит в том, что вызов 'sizeof' на них даст неверный результат.
Еще одна проблема состоит в том, что попытка создать копию структуры может приводить к неожиданным результатам, даже если размер вычислен верно. Рассмотрим соответствующий пример:
typedef struct
{
size_t len;
int data[];
} S;
S* make_copy(S *s)
{
S *copy = malloc(sizeof(S) + (s->len * sizeof(int)));
*copy = *s;
return copy;
}
Здесь, несмотря на то что выделено правильное количество памяти, в копию структуры попадет только поле 'len'.
Часто для объявления flexible-массивов может использоваться такой некорректный паттерн:
typedef struct
{
size_t len;
int data[1];
} S;
Компилятор может трактовать выход за границу такого массива в один элемент как неопределенное поведение и оптимизировать код непредсказуемым образом.
Данная диагностика классифицируется как:
|