V2589. MISRA. Casts between a pointer and a non-integer arithmetic type should not be performed.
Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Это правило актуально только для C. Преобразование выражений нецелочисленных типов к указателю и наоборот может привести к неопределённому поведению.
Стандарт MISRA определяет следующую модель сущностных типов (Essential type model), в которой переменная может иметь тип:
- 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 { .... };'
Преобразование сущностного 'Boolean', 'character' или 'enum' типа к указателю может привести к формированию указателя с неверным выравниванием, что ведёт к неопределённому поведению. Пример:
enum Nums
{
ONE,
TWO,
....
};
double* bar(Nums num)
{
....
return (double*)num;
}
Преобразование указателя к вышеописанным сущностным типам может привести к тому, что результирующее значение не может быть представлено в выбранном сущностном типе, что также приводит к неопределённому поведению. Пример:
void foo(void)
{
....
char *a = "something";
char b = a;
....
}
Преобразование сущностного 'floating' типа к указателю или наоборот ведёт к неопределенному поведению. Пример:
void foo(short *p)
{
// ....
float f = (float) p;
// ....
}
Данная диагностика классифицируется как:
|