# V206. Explicit conversion from 'void *' to 'int *'.

Предупреждение информирует о наличии явного приведения типа `void *`, `byte *` к указателю на функцию или к указателю на 32/64-битные целочисленные типы данных, или наоборот. Cамо по себе такое приведение типа не является ошибкой.

Достаточно часто указатель на какой-то буфер памяти передаётся в другую часть программы с помощью указателя на байт или void. Причины написать такой код могут быть различны. Часто это свидетельствует о плохом дизайне. Указатели на функцию тоже часто хранятся как `void *`.

В каком-то фрагменте программы указатель на массив/функцию сохраняется как `void *`, а в другом происходит обратное приведение типа. При портировании в таком коде появляются ошибки. В одном месте тип данных может быть изменён, а в другом — нет.

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

    size_t array[20];
    void *v = array;
    ....
    unsigned* sizes = (unsigned*)(v);

Этот код корректно работает в 32-битном режиме, так как размеры типов `unsigned` и `size_t` совпадают. В 64-битном режиме размер типов отличается, и поведение программы также будет отличаться от ожидаемого. См. также: паттерн 6 — изменение типа массива.

Анализатор указывает на строку с явным приведением типа, которая содержит ошибку. Исправленный вариант кода может выглядеть так:

    unsigned array[20];
    void *v = array;
    ....
    unsigned* sizes = (unsigned*)(v);

Или так:

    size_t array[20];
    void *v = array;
    ....
    size_t* sizes = (size_t*)(v);

Аналогичную ошибку можно допустить при работе с указателями на функцию.

    void Do(void *ptr, unsigned a)
    {
      typedef void (*PtrFoo)(DWORD);
      PtrFoo f = (PtrFoo)(ptr);
      f(a);
    }

    void Foo(DWORD_PTR a) { /*... */ }

    void Call()
    {
      Do(Foo, 1);
    }

Исправленный вариант кода:

    typedef void (*PtrFoo)(DWORD_PTR);

Примечание. Анализатор распознает множество случаев, когда явное приведение типа безопасно. Например, он не обращает внимание на явное приведение указателя типа `void *`, который вернула функция `malloc()`:

    int *p = (int *)malloc(sizeof(int) * N);

Как было отмечено в начале, явное приведение типа само по себе не является ошибкой. Поэтому несмотря на большое количество исключений из правила, анализатор всё равно генерирует много ложных предупреждений V206. Анализатор не знает, есть ли в программе другие места, где неправильно используются эти указатели, поэтому он выдаёт предупреждения на все потенциально опасные приведения типов.

Например, выше были приведены два примера некорректного кода и способы их исправления. Анализатор будет продолжать выдавать предупреждения на уже исправленный код.

Существует следующий способ работы с предупреждением: один раз внимательно просмотреть все сообщения V206, после чего отключить эту диагностику в настройках. Если ложных срабатываний немного, то можно воспользоваться один из методов подавления ложных предупреждений.