Определение «единицы выделения» в C ++? - PullRequest
0 голосов
/ 16 февраля 2019

Стандарт C ++ 17 несколько раз использует термин «единица выделения» в разделе 12.2.4 при обсуждении битовых полей, но, похоже, не определяет, что означает этот термин.Стандарт также гласит: «В качестве особого случая безымянное битовое поле с шириной нуля определяет выравнивание следующего битового поля на границе единицы выделения».

Итак, у меня есть два вопроса относительно этих концепцийс использованием приведенного ниже кода в качестве примера:

  1. Что означает стандарт под термином «единица распределения»?

  2. Какое значение имееттипа данных, указанного для безымянных битовых полей?

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

struct tag
{
   char X:3;
   unsigned int :0;   // start next bit-field on next unsigned int boundary?
   char Y:4;
   unsigned char :0;  // start next bit-field on next unsigned char boundary?
   long Z:32;
};

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

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

Термин «единица выделения» является намеренно расплывчатым.Это определение действительно подразумевается:

Распределение битовых полей внутри объекта класса определяется реализацией.Выравнивание битовых полей определяется реализацией.Битовые поля упакованы в некоторую адресуемую единицу выделения .[выделение добавлено] [class.bit] / 1

Реализация должна сказать вам, что означает «единица выделения».Единственное другое требование состоит в том, что единица выделения должна быть «адресуемой».Это единственное место, где используется слово «адресуемый», так что вы все еще одни.

0 голосов
/ 16 февраля 2019

Я полагаю, что термин «единица выделения» относится к размеру типа битового поля.

Ссылка CPP на битовые поля состояния:

Специальное безымянное битовое поле нулевого размера может быть принудительно разбито для заполнения.Он указывает, что следующее битовое поле начинается в начале его единицы выделения:

Я изменил пример из ссылки CPP на битовые поля , чтобы проиллюстрировать это.

#include <iostream>
struct S1 {

    unsigned char b1 : 1;
    //unsigned char :0; // #1. start a new byte
    unsigned char b2 : 1;

};

struct S2 {

    unsigned int b1 : 10;
    //unsigned int :0; // #2. start a new int
    unsigned int b2 : 10;

};

int main()
{
    std::cout << sizeof(char) << '\n'; 
    std::cout << sizeof(int) << '\n'; 
    std::cout << sizeof(S1) << '\n'; // usually prints 1
    std::cout << sizeof(S2) << '\n'; // usually prints 4

}

Размеры S1 и S2 будут равны 1 и 4 соответственно, которые также являются размерами char и int.Это то, что мы обычно ожидаем.
Но если я раскомментирую строки #1 и #2 в описаниях структуры выше, размеры S1 и S2 будут 2 и 8 соответственно.Это является следствием утверждения, которое вы процитировали в вопросе:

В особом случае безымянное битовое поле с нулевой шириной задает выравнивание следующего битового поля в единице выделения.border. "

Live Demo

...