Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V2596. MISRA. The value of a...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

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

25 Авг 2025

Диагностическое правило основано на руководстве 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