﻿# V2611\. MISRA\. Casts between a pointer to an incomplete type and any other type shouldn't be performed\.

Данное диагностическое правило основано на руководстве [MISRA](https://www.misra.org.uk/) \(Motor Industry Software Reliability Association\) по разработке программного обеспечения\.

Это правило актуально только для С\. Преобразование с использованием указателя на неполный тип может привести к получению неверно выравненного указателя, что может повлечь за собой неопределённое поведение\. Такая же ситуация происходит при преобразовании между указателями на неполный тип и числами с плавающей точкой\.

Также указатели на неполный тип иногда используются для сокрытия реализации \(идиома PIMPL\), а приведение к указателю на объект нарушает эту инкапсуляцию\.

Рассмотрим пример:

```cpp
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' – явное, но уже из неполного типа в полный\. Оба эти случая могут привести к неопределённому поведению\.



При этом у правила есть два исключения:

* Константа нулевого указателя \('NULL'\) может быть приведена к указателю на неполный тип\.
* Указатель на неполный тип может быть преобразован в 'void'\.

Оба этих случая можно рассмотреть в функции 'baz':

```cpp
typedef struct _First First;

First* foo(void);

void baz(void)
{
    First *f = NULL;
    (void)foo();
}
```