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