Подтвердить что ты не робот

Что означает бит-поле без названия нулевой длины в C?

Я видел следующий пример в стандартном черновике C (n1570):

$3.14, пункт 4: Структура, объявленная как:

struct 
{
        char a;
        int b:5, c:11, :0, d:8;
        struct 
        { 
            int ee:8; 
        } e;
}

Итак, Что означает :0?

Я знаю, что такое бит-поле, но :0 не имеет имени, которое я не понимаю.

В чем цель :0 без какого-либо идентификатора?

4b9b3361

Ответ 1

Прежде всего, см. главу §6.7.2.1, Спецификаторы структуры и объединения, P11. В нем говорится:

Реализация может выделять любой адресный блок хранения, достаточно большой для хранения битового поля. Если остается достаточно места, бит-поле, которое сразу же следует за другим битовым полем в структура должна быть упакована в соседние биты того же блока. [...]

Но в случае, если мы явно хотим, чтобы два последовательных элемента бит-поля, которые "могли быть" упакованы в одно место для хранения, чтобы находиться в отдельной ячейке памяти (то есть адресной единице хранения), вышеописанный способ принуждения Это.

Следующий параграф, P12, упоминает,

Объявление битового поля без декларатора, но только двоеточие и ширина, указывает на неназванное битовое поле. 126). В качестве особого случая элемент структуры битового поля с шириной 0 указывает, что никакое дополнительное битовое поле не должно быть упаковано в блок, в котором было добавлено предыдущее бит-поле, если оно есть.

следуя вашему примеру, это гарантирует, что два элемента битового поля, окружающие :0, будут находиться в отдельной ячейке памяти (не внутри одного адресного блока хранения, даже если достаточное количество памяти осталось, чтобы упаковать их в один). Это имеет аналогичный эффект наличия члена, отличного от битового поля, между двумя битовыми полями, чтобы обеспечить разделение места памяти.

Цитата C11, глава §3.14, NOTE 2 (выделено мной)

Битовое поле и соседний элемент небитового поля находятся в отдельных ячейках памяти. Такой же применяется к двум битовым полям, если объявлено внутри объявления вложенной структуры, а другое - нет или , если два разделены объявлением битового поля нулевой длины, или если они разделены членом небитового поля декларация.

Кроме того, в отношении использования ( "почему это необходимо" )

[...] Битовые поля b и c не могут быть одновременно но b и a, например, могут быть.


Приложение:

Что касается части concurrency, из ПРИМЕЧАНИЕ 1

Два потока выполнения могут обновлять и получать доступ к отдельным ячейкам памяти без вмешательства друг с другом.

и, из главы §5.1.2.4/P1,

В рамках размещенной реализации программа может иметь более одного потока выполнения (или поток) одновременно. [...]

Итак, это теоретически жизнеспособный вариант, согласно стандарту.

Ответ 2

Как связанный вами документ объясняет прямо:

Поле бит и соседний элемент небитового поля находятся в отдельных ячейках памяти. То же самое относится к двум битовым полям, если объявлено внутри объявления вложенной структуры, а другое нет, или , если они разделены объявлением битового поля нулевой длины, или если они разделяются объявлением члена небитового поля

Это способ сообщить компилятору, что b и c могут/будут находиться в одной и той же ячейке памяти, тогда как d должны быть отделены от них и могут быть изменены одновременно с b/c

Ответ 3

Это способ гарантировать, что бит файлы, которые в противном случае могут быть объединены в одно место памяти, не являются.

Например, скажем, у вас есть 8-битный символ, но вы хотели бы, чтобы ваши два 3-битных поля были в разных местах (и, следовательно, могли быть изменены одновременно). Для этого вы можете использовать:

struct xyzzy {
    int first  : 3,
               : 0,
    int second : 3;
};

и вам не придется беспокоиться о том, чтобы заполнить пространство вручную, например, с помощью junk : 5.

Для юристов языка C11 3.14 memory location /3 указывает (мой акцент):

Поле бит и соседний элемент небитового поля находятся в отдельных ячейках памяти. То же самое относится к двум битовым полям, если объявлено внутри объявления вложенной структуры, а другое нет, или если они разделены объявлением битового поля нулевой длины или если они разделены небитом -field.