# V2596. MISRA. The value of a composite expression should not be assigned to an object with wider essential type.

Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.

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

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

Рассмотрим следующий фрагмент кода:

    void foo()
    {
      ....
      uint16_t var_a = 30000;
      uint16_t var_b = 40000;
      uint32_t var_sum;
      var_sum = var_a + var_b;  /* var_sum = 70000 or 4464? */
      ....
    }

При вычислении значения, которое будет присвоено переменной `var_sum`, происходит неявное преобразование из типа `uint16_t` к `int`. Как следствие, результат присваивания зависит от размера типа `int`:

- если `int` имеет 32-битный размер, то вычисления будут выполнены по модулю `2^32`, и в переменную `var_sum` будет записано ожидаемое значение `70000`;
- если `int` имеет 16-битный размер, то вычисления будут выполнены по модулю `2^16`, и в переменную `var_sum` будет записано значение `70000 % 65536 == 4464`.

Стандарт MISRA C определяет собственную модель типов — Essential type model.

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

Код выше можно исправить, используя явное преобразование к `uint32_t`:

    void foo()
    {
      ....
      uint16_t var_a = 30 000;
      uint16_t var_b = 40 000;
      uint32_t var_sum;
      var_sum = (uint32_t)var_a + var_b;  /* var_sum = 70 000 */
      ....
    };

Теперь вычисления происходят по модулю `2^32` независимо от того, какой размер имеет `int`, и ошибка не возникает, даже если `int` имеет 16-битный размер.

Данная диагностика классифицируется как:

MISRA-C-2012-10.6 MISRA-C-2023-10.6