>
>
>
V2620. MISRA. Value of a composite expr…


V2620. MISRA. Value of a composite expression should not be cast to a different essential type category or a wider essential type.

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

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

Рассмотрим пример:

int32_t foo(int16_t x, int16_t y)
{
  return (int32_t)(x * y);
}

Несмотря на то, что на типичных платформах (x86/ARM) тип 'int16_t' соответствует типу 'short', и при вычислении выражения он расширится до типа 'int', на других платформах (например, 16-битных микроконтроллерах) 'int16_t' может соответствовать типу 'int', поэтому расширения до 32 бит не произойдет, из-за чего в умножении возможно переполнение.

Исправленным вариантом может быть:

int32_t foo(int16_t x, int16_t y)
{
  return (int32_t)x * y;
}

В этом случае вычисление всего выражения будет происходить в более широком типе 'int32_t'.

Рассмотрим другой пример:

int32_t sum(float x, float y)
{
  return (int32_t)(x + y);
}

Согласно модели сущностных типов, результирующий тип выражения относится к floating категории, а тип 'int32_t' к signed категории сущностных типов. Приведение результата сложения к целому типу ведет к потери точности. Результат сложения двух чисел типа 'float' также может быть больше, чем верхний предел диапазона типа 'int32_t'.

Допустимым вариантом может быть:

float sum(float x, float y)
{
  return x + y;
}

Если в дальнейшем требуется привести результат выражения к типу 'int', то необходимо выполнить:

  • проверку на то, что конвертируемое значение входит в диапазон значений типа;
  • использовать функцию округления до целого.

В модели сущностных типов (Essential Type Model) определено 6 категорий:

  • 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 { .... };'.

Тип составного выражения в этой модели определяется таким образом, как если бы расширения до 'int' (integer promotion) не происходило.

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

  • MISRA-C-10.8