2011-11-20 5 views
4

나는이 같은 표준 레이아웃 유형이있는 경우이 같은노동 조합은 표준 레이아웃 유형입니까?

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 표준이 9.5-1을 참조하여 sl_t :: a 및 un_t :: b에 모두 액세스 할 수 있다는 것을 이미 알고 있다는 것에 유의하십시오.

+2

하지만 ... 'obj.b'가 더 짧고 안전하지 않습니까? 나는 당신의 동기에 대해 궁금합니다. –

+0

나는 아직도 실제로 그 주위에 reinterpret_cast가 필요할 것이다. 나는 주로 호기심이 있지만, 실제로 이것에 의존하는 것이 편리한 경우가 있습니다. –

답변

3

보이는 것 같습니다. pragma pack을보세요. 구조체/공용체 이름은 할당 된 메모리 블록을 참조하기 만합니다. st_t.a가 구조체에서 더 많은 멤버를 추가하여 옮겨지면 캐스트가 실패하지만 첫 번째 멤버로 유지되면 모든 공용 멤버가 노동 조합 자체와 같은 주소.

C++ 표준의 9.2.17 - 21 섹션 참조 : "reinterpret_cast를 사용하여 적절히 변환 된 표준 레이아웃 구조체 객체에 대한 포인터가 초기 멤버를 가리킴 (또는 해당 멤버가 비트 필드 , 그 유닛이 상주하는 유닛으로), 반대의 경우도 마찬가지입니다. "

참조 9.5 공용체 : "1. 공용체에서 비 정적 데이터 멤버는 하나만 활성화 할 수 있습니다. 즉, 비 정적 데이터의 최대 하나의 값 멤버는 언제든지 유니온에 저장할 수 있습니다. [참고 : 유니온의 사용을 단순화하기 위해 한 가지 특별한 보장이 있습니다. 표준 레이아웃 유니온에 공통 초기 시퀀스 (9.2)를 공유하는 여러 표준 레이아웃 구조체가 포함 된 경우, 이 표준 레이아웃 조합형의 객체가 표준 레이아웃 구조체 중 하나를 포함하는 경우 표준 레이아웃 구조체 멤버 중 공통 초기 시퀀스를 검사 할 수 있습니다 (9.2 참조). - end note] 유니온의 크기 가장 큰 비 정적 데이터 멤버를 포함하기에 충분합니다. 각각의 비 정적 데이터 멤버는 마치 구조체의 유일한 멤버처럼 할당됩니다. "

+0

필자는 컴파일러 확장없이 유효한지 여부에 관심이 있습니다. –

+0

@ edA-qa mort-ora-y : 나는 나의 대답을 확장했다. 그렇다. – slashmais

+1

두 번째 의견은 표준에서 실제로 조합원의 주소가 주소 자체와 동일하다는 것을 보증합니까? 그것이 내가 찾지 못한 것이지만, 그렇습니다, 그것은 나의 전환을 유효하게 할 것입니다. 그리고 예, 분명히 st_t.a가 더 이상 최초의 멤버가 아니면 작동하지 않습니다. –