﻿# V2572\. MISRA\. Value of the expression should not be converted to the different essential type or the narrower essential type\.

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

Диагностическое правило актуально только для C\.

Язык C предоставляет свободу при проведении присваиваний между переменными различных арифметических типов\. Однако неявные преобразования при подобных присваиваниях могут приводить к неочевидным проблемам, таким как потеря знака, точности или значимости\.

Стандарт MISRA C определяет собственную модель типов — [Essential type model](https://pvs-studio.ru/ru/blog/terms/7007/)\.

Используя модель сущностных типов, можно уменьшить количество подобных неочевидных проблем путем присваивания переменным значений одного и того же сущностного типа\. При этом разрешается присваивать переменной более широкого сущностного типа значения более узкого типа\. Запрещается производить неявные преобразования значений из одного сущностного типа в другой\.

Исключения:

* неотрицательное константное выражение `essential signed` типа может быть присвоено объекту `essential unsigned` типа, если значение может быть представлено в этом типе;
* инициализатор `{ 0 }` может использоваться для инициализации агрегатного типа или объединения\.

Пример кода, на который анализатор выдаст предупреждения:

```cpp
typedef enum ENUM {ONE} ENUM;

void Positive(signed char x)
{
  unsigned char      uchr = x; // <=
  unsigned short     usht = x; // <=
  unsigned int        uit = x; // <=
  unsigned long       ulg = x; // <=
  unsigned long long ullg = x; // <=

  long double ld = 0.0;
  double d = ld;        // <=
  float f = d;          // <=

  ENUM e = x; // <=
}
```

Пример корректного кода:

```cpp
enum {ONE = 1, TWO, THREE, FOUR, FIVE, SIX, 
      MUCH = 123123, MORE = 0x7FFFFFFF-1};

void Negative()
{
  signed char c = ONE;        // ok
  signed short h = TWO;       // ok
  signed int i = THREE;       // ok
  signed long long ll = FOUR; // ok

  unsigned char uc = FIVE;       // ok
  unsigned short uh = SIX;       // ok
  unsigned int ui = MUCH;        // ok
  unsigned long long ull = MORE; // ok

  float f = 0.0f;     // ok
  double d = f;       // ok
  long double ld = d; // ok

  ENUM e = c; // ok
}
```