С C ++ черновик 2019-04-12 conv.prom 7.3.6p5 :
7.3.6 Интегральные продвижения
Премия зацелочисленное битовое поле ([class.bit]) может быть преобразовано в значение типа int, если int может представлять все значения битового поля;
Из C ++ черновик2019-04-12 expr.shift 7.6.7p1 :
7.6.7 Операторы сдвига
Операторы сдвига << и >> группируются слева направо.
...
Операнды должны быть целочисленного или незаданного типа перечисления, и выполняются интегральные преобразования.
typeid(c.x)
равно uint32_t
, однако при использовании оператора <<
оно неявно преобразуется в int
.
c.x
равно 0x1
.Выражение c.x << 31
равно 0x1 << 31
, равно 0x80000000
(при условии sizoef(int) == 4
и CHAR_BIT == 8
).Это число интерпретируется как int
, а в формате дополняет два оно равно -2147483648
(INT_MIN
или что std::intergral_limits<int>::min()
).
Обратите внимание, что выражение c.x << 31
в настоящее время (C ++ 17) вызывает неопределенное поведение из-за переполнения целых чисел со знаком.
Кроме того, какое значение имеет тип, объявленный тогда в определении класса?
Перетяжка.Некоторые компиляторы интерпретируют разные типы битовых полей как «разделители-заполнители» (не знаю, как их назвать).Если следующий член в структуре имеет тип, отличный от предыдущего (оба являются битовым полем), то я ожидаю, что компилятор поместит второй член, начиная с нового «свежего» байта.Я ожидал бы, что c.x
и c.y
будут иметь битовые отступы между ними, поскольку они имеют различный тип.Если это будет struct C { uint32_t y : 2; uint32_t x : 2; }
, то компилятор с большей вероятностью поместит их в один и тот же байт.Обратитесь к документации по вашему компилятору или другим ресурсам .