V2593. MISRA. Single-bit bit fields should not be declared as signed type.
Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Это правило актуально только для C. Однобитные битовые поля не стоит объявлять со знаковым типом. Согласно стандарту C99 §6.2.6.2, однобитное битовое поле знакового типа имеет один бит для знака и ноль — для значений. При любом представлении целых чисел ноль значащих бит не могут специализировать какое-либо значимое число.
Несмотря на то, что C90 не имеет такого описания, правило применяется также и для этой версии стандарта.
Рассмотрим пример:
struct S
{
int a : 1;
};
void foo()
{
struct S s;
s.a = 1;
if (s.a > 0)
{
DoWork();
}
}
Несмотря на то, что в битовое поле явно присваивается '1', проверка на то, что оно больше нуля, не сработает. Поскольку в зависимости от реализации компилятора, единица в поле 's.a' может быть интерпретирована как знаковый бит. При привидении типов для сравнения к типу 'int' получится число '-1' (0xFFFFFFFF). В результате функция 'DoWork()' не будет выполнена, поскольку условие '-1 > 0' ложно. Корректный вариант:
struct S
{
unsigned a : 1;
};
void foo()
{
struct S s;
s.a = 1u;
if (s.a > 0u)
{
DoWork();
}
}
Исключением являются безымянные битовые поля, поскольку нельзя использовать значение из такого поля:
struct S
{
int a : 31;
int : 1; // ok
};
Данная диагностика классифицируется как:
|