Данное диагностическое правило основано на руководстве 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;
Компилятор может трактовать выход за границу такого массива в один элемент как неопределенное поведение и оптимизировать код непредсказуемым образом.
Данная диагностика классифицируется как:
|