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

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

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

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

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

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

Исключения:

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

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

Пример правильного с точки зрения этой диагностики кода:

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
}

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

  • MISRA-C-10.3