﻿# V2005\. C\-style explicit type casting is utilized\. Consider using: static\_cast/const\_cast/reinterpret\_cast\.

Данное диагностическое предупреждение добавлено по просьбе пользователей\.

Анализатор позволяет обнаружить явные приведения типов в программе на C\+\+, написанные в старом стиле языка C\. В языке C\+\+ более безопасно явно приводить типы с использованием операторов 'static\_cast', 'const\_cast'  и 'reinterpret\_cast'\.

Диагностическое правило V2005 помогает выполнить рефакторинг кода, поменять старый стиль приведения типов на новый\. Иногда это позволяет выявить ошибки\.

Примеры конструкций, на которые анализатор выдаст данное диагностическое сообщение: 

```cpp
int i;
double d;
size_t s;
void *p;
....
i = int(p);      //+V2005
d = (double)i;   //+V2005
s = (size_t)(d); //+V2005
```

Диагностическое сообщение V2005 не выдается в следующих случаях:

1\. Это программа на языке C\.

2\. Осуществляется приведение к типу 'void'\. Такое приведение типа никакой опасности в себе не несёт и используется, чтобы подчеркнуть, что некий результат никак не используется\. Пример:

```cpp
(void)fclose(f);
```

3\. Приведение типа находится в макросе\. Если выдавать предупреждения для макросов, то будет огромное количество срабатываний при использовании различных системных констант и макросов\. Причем, поправить их все равно нет никакой возможности\. Примеры:

```cpp
#define FAILED(hr) ((HRESULT)(hr) < 0)
#define SRCCOPY (DWORD)0x00CC0020
#define RGB(r,g,b)\
((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))\
|(((DWORD)(BYTE)(b))<<16)))
```

## Уровни достоверности диагностики

По умолчанию срабатывания V2005 диагностики имеют второй уровень достоверности \(Medium\)\. Если подозрительный код находится в шаблоне, а приведение происходит к типу шаблонного параметра, то уровень предупреждения снижается до третьего \(Low\)\. 

Рассмотрим синтетический пример:

```cpp
template <typename TemplateParam>
void foo(const std::vector<SomeType>& vec)
{
  auto a = (TemplateParam)(vec[0]); //+V2005 //3rd level
  auto b = TemplateParam(vec[3]);   //+V2005 //3rd level
  // ....
  auto i = (int)a; //+V2005 //2 level
  auto i = int(a); //+V2005 //2 level
  // ....
}
```

Без инстанцирований шаблона понять, что за тип скрывается под 'TemplateParam', сложно\. Если же приведение происходит к известному типу внутри шаблона, то анализатор будет по\-прежнему выдавать срабатывания второго уровня\. В случае, если предупреждения третьего уровня не имеют практической пользы для вас, их можно подавить при помощи [специального комментария](https://pvs-studio.ru/ru/docs/manual/0017/):

```cpp
//-V::2005:3
```

## Особые настройки диагностики V2005

По дополнительной просьбе пользователей появилась возможность управлять поведением диагностики V2005\. В общем заголовочном файле или pvsconfig\-файле пишется комментарий специального вида\. Пример использования:

```cpp
//+V2005 ALL
```

Существует три режима:

а\) Режим по умолчанию: на каждое преобразование типов в стиле C выдаётся предупреждающее сообщение, которое гласит: используйте вместо преобразования типов конструкции вида 'static\_cast', 'const\_cast' и 'reinterpret\_cast'\.

б\) ALL \- на каждое преобразование типов в стиле C анализатор выдаёт рекомендацию о том, какое ключевое слово \(ключевые слова\) требуется использовать вместо него\. Изредка возможны единичные неверные рекомендации, связанные с преобразованием сложных шаблонных типов\. Также изредка возможна такая ситуация, что анализатор не сможет определить тип преобразования и выдал обыкновенное сообщение без точного указания типа приведения\.

```cpp
//+V2005 ALL
```

в\) NO\_SIMPLE\_CAST \- аналогично предыдущему, но сообщение показывается только если в преобразовании участвует хотя бы один указатель или требуется преобразование сложнее чем static\_cast\.

```cpp
//+V2005 NO_SIMPLE_CAST
```

**Дополнительные ссылки:**

1. Терминология\. [Явное приведение типов\.](https://pvs-studio.ru/ru/blog/terms/0015/) 
1. Wikipedia\. [Приведение типа\.](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%B0)