Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Это правило актуально только для С. Преобразование с использованием указателя на неполный тип может привести к получению неверно выравненного указателя, что может повлечь за собой неопределённое поведение. Такая же ситуация происходит при преобразовании между указателями на неполный тип и числами с плавающей точкой.
Также указатели на неполный тип иногда используются для сокрытия реализации (идиома PIMPL), а приведение к указателю на объект нарушает эту инкапсуляцию.
Рассмотрим пример:
typedef struct _First First;
typedef struct _Second
{
int someVar;
} Second;
void foo(void)
{
First *f;
Second t;
...
f = &t; // <=
...
}
Second* bar(First *ptr)
{
return (Second*)ptr; // <=
}
В приведённом выше коде объявляются структуры 'First' и 'Second'. При этом тип 'First' является не полным, т. к. отсутствует его определение. Далее в функции 'foo' происходит неявное приведение указателя к неполному типу, а в функции 'bar' – явное, но уже из неполного типа в полный. Оба эти случая могут привести к неопределённому поведению.
При этом у правила есть два исключения:
Оба этих случая можно рассмотреть в функции 'baz':
typedef struct _First First;
First* foo(void);
void baz(void)
{
First *f = NULL;
(void)foo();
}
Данная диагностика классифицируется как:
|