четверг, 1 апреля 2021 г.

Записали 1, прочитали -1. Как?

Представим, что мы в отладчике проходим по коду и видим запись значения 1, но следом это же значение читается как -1. Как это может быть и где искать проблему?
tt_t tt;
tt.s = 1;

bool b11 = tt.s > 0; // false
bool b12 = tt.s < 0; // true
Вспоминаем, что записано в одном бите: https://thedarkaugust.blogspot.com/2018/04/blog-post_21.html

Описанная ситуация происходит если поле s является знаковым целым битовым полем.
struct tt_t
{
  signed int s : 1;
};

tt_t tt;
tt.s = 1;
bool b11 = tt.s > 0; // false
bool b12 = tt.s < 0; // true
Поскольку при чтении значение приводится расширением знака к максимальному целому, а в качестве знака берется старщий бит, то в случае битового поля из одного бита этот бит и является знаком. Именно им расширяется результат чтения от оставшихся битов, а поскольку от знака осталось ноль битов, то знак расширяется на все биты результата.

В итоге мы из одного бита читаем, действительно, лишь знак, у которого нет самого числа. И именно поэтому во всех учебниках строго сказано - используешь битовые поля - не думай, а используй строго unsigned типы.

Комментариев нет:

Отправить комментарий