Является ли объединение типом стандартного макета? - PullRequest
4 голосов
/ 20 ноября 2011

Если у меня есть стандартный тип макета, подобный этому:

struct sl_t
{
  int a;
};

И объединение, подобное этому:

union un_t
{
  int b;
  double q;
};

Могу ли я привести и использовать объединение в качестве типа структуры?То есть можно ли предположить, что само объединение является типом стандартной компоновки и данные выровнены в начале памяти?

un_t obj;
sl_t * s = reinterpret_cast<sl_t*>(&obj);
s->a = 15;
assert( obj.b == 15 );

Или я должен взять адрес переменной в объединении &obj.b?

Обратите внимание, что я уже знаю, что если я сохраню структуру внутри объединения, стандарт C ++ 11 гарантирует, что я могу получить доступ как к sl_t :: a, так и к un_t :: b, ссылаясь на 9.5-1.

1 Ответ

3 голосов
/ 20 ноября 2011

Кажется, выравнивание - ваша проблема, посмотрите на pragma pack. Имена struct / union просто ссылаются на выделенный блок памяти, если st_t.a сместится в структуру путем добавления большего числа членов, произойдет сбой приведения, но если он останется первым, он будет работать, поскольку все члены объединения указывают на тот же адрес, что и сам союз.

См. Раздел 9.2.17 - 21 C ++ - стандарт: «Указатель на объект структуры стандартной компоновки, соответствующим образом преобразованный с использованием reinterpret_cast, указывает на его начальный элемент (или, если этот элемент является битовым полем, затем на модуль, в котором он находится), и наоборот.»

См. Также раздел 9.5 Союзы: «1. В объединении в любое время может быть активен не более одного из элементов не статических данных, то есть значение не более одного из элементов не статических данных может быть сохранено в объединении в любое время. [Примечание: одна специальная гарантия сделана для упрощения использования объединений: если объединение стандартного макета содержит несколько структур стандартного макета, которые имеют общую начальную последовательность (9.2), и если объект этого типа объединения стандартного макета содержит одну из структур стандартного макета, разрешено проверять общую начальную последовательность любого из элементов структуры стандартного макета, см. 9.2. - примечание к концу] Размер объединения достаточен, чтобы содержать наибольшее из его нестатических члены данных. Каждый нестатический элемент данных выделяется так, как если бы он был единственным членом структуры. "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...