﻿# V2531\. MISRA\. Expression of essential type 'foo' should not be explicitly cast to essential type 'bar'\.

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

Данное диагностическое правило актуально только для C\. Значение одного сущностного типа не должно быть приведено явно к значению другого несоответствующего сущностного типа\. 

Стандарт MISRA определяет следующую модель сущностных типов \(Essential type model\), в которой переменная может иметь тип:

* **Boolean**, если оперирует булевыми значениями true/false: '\_Bool';
* **signed**, если оперирует знаковыми целыми числами, или является безымянным enum: 'signed char', 'signed short', 'signed int', 'signed long', 'signed long long', 'enum \{ \.\.\.\. \};';
* **unsigned**, если оперирует без знаковыми целыми числами: 'unsigned char', 'unsigned short', 'unsigned int', 'unsigned long', 'unsigned long long';
* **floating**, если оперирует числами с плавающей точкой: 'float', 'double', 'long double';
* **character**, если оперирует только символами: 'char';
* **Именованный enum**, если оперирует с именованным множеством определенных пользователем значений: 'enum name \{ \.\.\.\. \};'

Указатели в этой модели отсутствуют\.

Таблица ситуаций, которые желательно избегать:

![V2531_ru/image1.png](https://import.viva64.com/docx/blog/V2531_ru/image1.png)

Исключения: 

1. Переменная типа 'enum' может быть приведена к синониму этого же типа\.
1. Переменные, имеющие константные значения '0' и '1', могут быть приведены из целочисленного типа к 'Boolean'\.

Причины для явного преобразования типов:

* для внесения большей ясности;
* изменить тип, в котором последующая арифметическая операция будет выполнена;
* намеренное усечение \(срез\) значения \(при касте из большего типа в меньший, например, 'long' \-\> 'short'\)\.

По некоторым причинам преобразование из одного сущностного типа к другому может быть опасно или лишено смысла, например:

* преобразование значения целочисленного знакового/без знакового типа к типу именованного 'enum' может быть опасно, поскольку оно может не входить в диапазон, определяемый максимальным размером данного 'enum' типа;
* преобразование булевого значения к любому другому обычно лишено смысла;
* преобразование между вещественными и символьными типами также лишено смысла, поскольку нет точного соответствия между этими двумя представлениями\.

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

```cpp
enum A {ONE, TWO = 2};

float foo(int x, char ch)
{
    enum A a = (enum A) x;  // signed to enum, may lead to 
                            // unspecified behavior

    int y = int(x == 4);    // Meaningless cast Boolean to signed

    return float(ch) + .01; // Meaningless cast character to floating,
                            // there is no precise mapping between
                            // two representations
}
```