Объявление объединения
Объединение — это тип, состоящий из последовательности членов, хранение которых перекрывается (в отличие от структуры, тип которой состоит из последовательности членов, хранение которых выделяется в упорядоченной последовательности). В объединении в любой момент времени может храниться значение не более одного члена.
Спецификатор типа типа для объединения идентичен спецификатору struct типа, за исключением ключевого слова:
Синтаксис
union attr-spec-seq (необязательно) name (необязательно) { struct-declaration-list } |
(1) | |
union attr-spec-seq (необязательно) name |
(2) |
| name | - | имя объявляемого объединения |
| struct-declaration-list | - | любое количество объявлений переменных, объявлений битовых полей и объявлений статических утверждений. Члены неполного типа и члены типа функции запрещены. |
| attr-spec-seq | - | (C23)необязательный список атрибутов, применяемых к типу объединения, не разрешается для (2), если такая форма не следует за ; (т.е. это не объявление вперёд). |
Объяснение
Объединение имеет размер, необходимый только для размещения его самого большого члена (также может быть добавлен дополнительный неименованный конечный отступ). Остальные члены размещаются в тех же байтах, что и этот самый большой член.
Указатель на объединение может быть преобразован в указатель на каждый из его членов (если объединение имеет члены-битовые поля, указатель на объединение может быть преобразован в указатель на базовый тип битового поля). Аналогично, указатель на любой член объединения может быть преобразован в указатель на содержащее его объединение.
|
Если член, используемый для доступа к содержимому объединения, не совпадает с членом, последний используемым для хранения значения, представление объекта сохранённого значения интерпретируется как представление объекта нового типа (это известно как приведение типов). Если размер нового типа больше размера последнего записанного типа, содержимое избыточных байтов не определено (и может быть представлением ловушки). До C99 TC3 (DR 283) такое поведение было неопределённым, но обычно реализовывалось таким образом. |
(с C99) |
|
Аналогично структурам, неименованный член объединения, тип которого является объединением без имени, известен как анонимное объединение. Каждый член анонимного объединения считается членом содержащей структуры или объединения, сохраняя их структуру объединения. Это применяется рекурсивно, если содержащая структура или объединение также являются анонимными. struct v
{
union // anonymous union
{
struct { int i, j; }; // anonymous structure
struct { long k, l; } w;
};
int m;
} v1;
v1.i = 2; // valid
v1.k = 3; // invalid: inner structure is not anonymous
v1.w.k = 5; // validАналогично структурам, поведение программы не определено, если объединение определено без каких-либо именованных членов (включая те, которые получены через анонимные вложенные структуры или объединения). |
(с C11) |
Ключевые слова
Примечания
См. инициализацию структур для правил инициализации структур и объединений.
Пример
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
int main(void)
{
union S
{
uint32_t u32;
uint16_t u16[2];
uint8_t u8;
} s = {0x12345678}; // s.u32 is now the active member
printf("Union S has size %zu and holds %x\n", sizeof s, s.u32);
s.u16[0] = 0x0011; // s.u16 is now the active member
// reading from s.u32 or from s.u8 reinterprets the object representation
// printf("s.u8 is now %x\n", s.u8); // unspecified, typically 11 or 00
// printf("s.u32 is now %x\n", s.u32); // unspecified, typically 12340011 or 00115678
// pointers to all members of a union compare equal to themselves and the union
assert((uint8_t*)&s == &s.u8);
// this union has 3 bytes of trailing padding
union pad
{
char c[5]; // occupies 5 bytes
float f; // occupies 4 bytes, imposes alignment 4
} p = {.f = 1.23}; // the size is 8 to satisfy float's alignment
printf("size of union of char[5] and float is %zu\n", sizeof p);
}Возможный вывод:
Union S has size 4 and holds 12345678 size of union of char[5] and float is 8
Ссылки
- Стандарт C23 (ISO/IEC 9899:2023):
- 6.7.2.1 Спецификаторы структур и объединений (стр: TBD)
- Стандарт C17 (ISO/IEC 9899:2018):
- 6.7.2.1 Спецификаторы структур и объединений (стр: 81-84)
- Стандарт C11 (ISO/IEC 9899:2011):
- 6.7.2.1 Спецификаторы структур и объединений (стр: 112-117)
- Стандарт C99 (ISO/IEC 9899:1999):
- 6.7.2.1 Спецификаторы структур и объединений (стр: 101-104)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 3.5.2.1 Спецификаторы структур и объединений
См. также
| Документация C++ для Объявление объединения |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/union