"может ли поле перекрывать границы слов, определяется реализацией.
Рассмотрим два слова памяти, где размер слова, скажем, 32 бита:
[31] [30] [29] ... [2] [1] [0] | [31] [30] [29] ... [2] [1] [0]
Если бы у нас была структура:
struct X
{
int a : 30;
int b : 4;
};
Тогда компилятор мог бы поставить поле b таким образом, чтобы часть была в каждом слове, или он мог бы оставить пробел, чтобы все b попадали во второе слово.:
[31] [30] [29] ... [2] [1] [0] | [31] [30] [29] [28] ... [2] [1] [0]
a--------------------a b-----------------b
OR
a--------------------a GAP b-----------------b
Почему он может оставить GAP? Потому что тогда, когда он хочет читать или писать b, ему нужно работать только с одним словом в памяти - это обычно быстрее и проще, и требует меньше инструкций процессора.
поля не должны быть именованы, для заполнения используются безымянные поля (только двоеточие и ширина).
Если бы мы изменили нашу более раннюю структуру, мы могли бы явно запроситьпробел:
struct X
{
int a : 30;
int : 2; // unnamed field
int b : 4;
};
Это говорит "оставьте 2 бита между a и b - им не нужен идентификатор (имя), потому что я никогда не буду спрашивать, что в них, или нужно будет спрашивать их значениебыть изменен ". Но вы не должны делать это 2 просто так, чтобы30 + 2 == 32 (размер нашего слова) ... вы можете спросить, какие промежутки вам нравятся, где угодно.Это может быть полезно, если вы имеете дело со значениями с какого-либо аппаратного устройства, и вы знали, какие были некоторые биты, но не другие, или вам просто не нужно было использовать некоторые из них - вы можете просто оставить их без названия для документированияВаша незаинтересованность при сохранении компилятором пространства именованных битовых полей с необходимыми смещениями в слове, необходимом для соответствия использованию оборудования.
специальная ширина 0 может использоваться для принудительного выравнивания по следующему словуborder. "
Это просто означает, что компилятор может вычислить, сколько бит осталось в частично заполненном слове, и перейти к началу следующего слова. Так же, как мы убедились, что b начал в новомслово, добавив 2-битное поле выше (учитывая, что a было 30 бит, а размер слова 32), мы могли бы иметь ...
struct X
{
int a : 30;
int : 0; // unnamed field
int b : 4;
};
... и компилятор сработаетДля нас 2. Таким образом, если мы изменим a на какой-то другой размер или закончим компиляцию для 64-битного размера слова, компилятор бесшумно адаптируется кПоведение без необходимости исправления безымянного поля.