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

This diagnostic rule is based on the [MISRA](https://www.misra.org.uk/) \(Motor Industry Software Reliability Association\) software development guidelines\.

This diagnostic rule is relevant only for C\.

The C language allows much flexibility in conversion between arithmetic types, but it can also lead to hidden problems such as loss of sign, loss value, or loss of precision\.

The MISRA C standard defines its own type model, called the [essential type model](https://pvs-studio.com/en/blog/terms/7007/)\.

Using the essential type model can help avoid many non\-obvious issues mentioned above by assigning values of the same essential type to variables\. Within this model, a variable of a wider type can be assigned a value of a narrower essential type\. Implicit conversions between different essential types are forbidden\.

Exceptions:

* A non\-negative constant expression of the `essential signed` type can be assigned to a variable of the `essential unsigned` type if its value can be represented by this type\.
* The `{ 0 }` initializer can be used to initialize an aggregate type or union\.

The example: 

```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; // <=
}
```

The fixed code:

```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
}
```