Program Language/C & C++

[C++] Unions

야곰야곰+책벌레 2022. 1. 4. 11:14
728x90
반응형

Union은 가장 큰 구성원만큼만 공간을 차지하도록 모든 구성원이 동일한 주소에 할당되는 구조체다. 당연히 Union은 한 번에 한 구성원에 대해서만 값을 보유할 수 있다. 예를 들어 이름과 값을 보유하는 기호 테이블 항목을 고려해 보자.

enum Type { str, num };
struct Entry {
	char∗ name;
	Type t;
	char∗ s; // use s if t==str
	int i; // use i if t==num
};
void f(Entry∗ p)
{
	if (p−>t == str)
		cout << p−>s;
	// ...
}

s와 i 멤버는 절대 동시에 사용할 수 없기 대문에 공간을 낭비하고 있다. 다음과 같이 둘 다 Union의 구성원이어야 함을 지정하여 쉽게 복구할 수 있다.

union Value {
	char∗ s;
	int i;
};

언어는 어떤 종류의 값이 공용체에 의해 유지되는지 추적하지 않으므로 프로그래머는 다음을 수행해야 한다.

struct Entry {
	char∗ name;
	Type t;
	Value v; // use v.s if t==str; use v.i if t==num
};
void f(Entry∗ p)
{
	if (p−>t == str)
		cout << p−>v.s;
	// ...
}

오류를 피하기 위해서 유형 필드와 union 멤버에 대한 액세스 간 일치가 보장될 수 있도록 union을 캡슐화할 수 있다. union은 때때로 '형 변환'에 잘못 쓰인다. 이러한 잘못된 방법은 주로 명시적인 유형 변환 기능이 없는 언어로 훈련된 프로그래머에 의해 이뤄지므로 cheating이 필요하다. 

예를 들어, 다음은 단순히 비트 동등성을 가정하여 int를 int*로 '변환'한다.

union Fudge {
	int i;
	int∗ p;
};
int∗ cheat(int i)
{
	Fudge a;
	a.i = i;
	return a.p; // bad use
}

이런 실제로 변환이 아니다. 어떤 machine에서는 int와 int*가 같은 공간을 차지하지 않는 반면, 다른 machine에서는 어떤 정수도 홀수 주소를 가질 수 없다. 이러한 조합의 사용은 위험하고 이식성이 없다. 본질적으로 보기 흉한 변환이 필요한 경우 작업자가 진행 상황을 볼 수 있도록 명시적 유형 변환 연산자를 사용하라.

int∗ cheat2(int i)
{
	return reinterpret_cast<int∗>(i); // obviously ugly and dangerous
}

여기에서 적어도 컴파일러는 객체의 크기가 다르고 그러한 코드가 눈에 띄는 경우 경고할 기회가 있다. union의 사용은 데이터 압축과 성능을 위해 필수적일 수 있다. 그러나 대부분의 프로그램은 union 사용으로 크게 개선되지 않으며 union은 오류가 발생하기 쉽다. 결과적으로 사용하지 않을 수 있다면 그러는 편이 좋다.

728x90
반응형

'Program Language > C & C++' 카테고리의 다른 글

[C++] 선언 명령문  (0) 2022.01.05
[C++] Enumerations  (0) 2022.01.04
[C++] 구조체의 필드(field)  (0) 2022.01.04
[C++] 구조체의 POD(plain old data)  (0) 2022.01.04
[C++] 구조체 타입 동등성  (2) 2022.01.03