uinion
- 유니온의 모든 멤버는 동일한 메모리 주소를 가리킨다. 유니온 메모리 크기는 멤버중 가장 큰 데이터 타입 크기로 할당된다.
- 비교 : 구조체 의 모든 멤버는 개별적으로 메모리 할당됨.
- union은 C 언어 시절부터 이어져 온 순수 하드웨어 친화적 문법. 컴파일러의 최적화 옵션 (-o2,-o3 같은것) 에 간섭받지 않고 개발자가 작성한 어셈블리 그대로 매핑
union MyUnion {
char i1; // 1 바이트
short i2; // 2 바이트
int i4; // 4 바이트 (가장 큼)
}; // 이 공용체의 전체 크기는 4바이트
union 활용예
- byte 내의 비트 접근시.
union Register {
uint8_t byte; // 1바이트 전체 제어
struct { // 비트 단위 세부 제어
uint8_t bit0 : 1; // 먼저 선언한것이 최하위비트 점함
uint8_t bit1 : 1;
uint8_t rsv : 6;
} bits;
};
union Register reg;
reg.byte = 0xFF; // 전체를 1로 세팅
reg.bits.bit0 = 0; // 특정 비트만 0으로 수정 (동일 메모리이므로 byte 값도 변함)
- 참고. 위 코드의 비트필드
컴파일러는 위 구조체를 보고 다음과 같이 처리함.
- uint8_t bit0 : 1; ➔ 방금 준비한 1바이트 중 1비트 사용
- uint8_t bit1 : 1; ➔ 이어서 1비트 사용
- uint8_t rsv : 6; ➔ 이어서 나머지 6비트 사용
- 총합: 1 + 1 + 6 = 8비트 (정확히 1바이트)
(MSB) ←───────────────────────────────────────── (LSB)
┌───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┐
│ bit 7 │ bit 6 │ bit 5 │ bit 4 │ bit 3 │ bit 2 │ bit 1 │ bit 0 │
├───────────┴───────────┴───────────┴───────────┴───────────┴───────────┼───────────┼───────────┤
│ rsv (3번째로 채워짐, 6비트) │ bit1 │ bit0 │
│ │(2번째) │(1번째) │
└───────────────────────────────────────────────────────────────────────┴───────────┴───────────┘
struct OnlyOneBit {
uint8_t bit0 : 1;
}; // sizeof(OnlyOneBit)는 컴파일 결과 1바이트.
//////////////////////////////////////////////////////
union CustomRegister {
uint8_t byte;
struct {
uint8_t bit0 : 1; // 사용함 (이름 있음)
uint8_t : 6; // 중간 6비트는 건너뜀 (이름 생략, 접근 불가능)
uint8_t bit7 : 1; // 사용함 (이름 있음)
} bits;
};
union CustomRegister reg;
reg.bits.bit0 = 1;
reg.bits.bit7 = 0;
// reg.bits. (컨트롤+스페이스를 눌러도 자동완성에 중간 6비트는 뜨지 않음)
//////////////////////////////////////////////////////
Bit 0: EN (활성화 플래그)
Bit 1: IE (인터럽트 허용 플래그)
Bit 2~15: RSV1 (예약 영역)
Bit 16~31: VAL (16비트짜리 데이터 세팅 값)
typedef union {
volatile uint32_t val32; // 32비트 전체 통제용 (4바이트)
struct {
volatile uint32_t EN : 1; // Bit 0 (최하위 비트)
volatile uint32_t IE : 1; // Bit 1
volatile uint32_t : 14; // Bit 2 ~ 15 (안 쓰는 14개 비트 건너뛰기)
volatile uint32_t VAL : 16; // Bit 16 ~ 31 (16비트 데이터 영역)
} bits;
} UART_CTRL_REG;
- 4바이트 단일 데이터 ↔ 4바이트 배열 전환
union DataConverter {
uint32_t value;
uint8_t bytes[4];
};
union DataConverter data;
data.value = 0x12345678;
// data.bytes[0]을 보면 엔디안(Endian)에 따라 0x78 또는 0x12를 바로 읽을 수 있음 (포인터 연산 불필요)
- 메모리 절약 용도
struct Token {
int type; // 토큰 종류 (문자열인지, 숫자인지)
union {
char* string_val; // type이 문자열일 때만 사용 (8바이트)
double number_val; // type이 숫자일 때만 사용 (8바이트)
} data;
}; // struct였다면 16바이트가 필요하지만, union이라 8바이트만 소모.
하드웨어 레지스터/비트 제어 시 ➔ volatile union
값이 컴파일러 모르게 하드웨어에 의해 언제든 바뀔 수 있음을 알리는것. 컴파일러는 이 메모리 접근을 절대 최적화로 생략하지 못한다.
typedef union {
volatile uint32_t WORD;
struct {
volatile uint32_t TX_READY : 1;
volatile uint32_t RX_READY : 1;
volatile uint32_t RESERVED : 30;
} BIT;
} UART_STATUS_REG;
첫 등록 : 2026.08.17
최종 수정 :
단축 주소 : https://igotit.tistory.com/
'VisualStudio.C++.C# > C . C++' 카테고리의 다른 글
| C++ . 네임스페이스 (0) | 2026.01.18 |
|---|---|
| C++ Embedded Python (임베디드 파이썬) . Python C API . pybind11 (0) | 2026.01.04 |
| VC++ 프로젝트 폴더 복사하여 작업 하는 경우 필수 삭제 해야할 것 (0) | 2025.04.09 |
| std::shared_mutex . 멀티 스레드 읽기 쓰기 락 (0) | 2024.09.12 |
| C/C++ . 부호 있는 정수 singed int . 음수 표현 규격 . 2's complement (0) | 2023.08.27 |
댓글