Данное диагностическое правило основано на руководстве 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(); }
Данная диагностика классифицируется как:
|