Данное диагностическое правило основано на руководстве 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 категорий:
Тип составного выражения в этой модели определяется таким образом, как если бы расширения до 'int' (integer promotion) не происходило.
Данная диагностика классифицируется как:
|