2010-05-21 2 views
3

노동 조합은 내가 자주 사용해온 것이 아니며 여기에 몇 가지 다른 질문을 한 후 작동하지 않을 수있는 거의 항상주의해야 할 것처럼 보입니다. 예 : 구조체에 예상치 못한 패딩 또는 엔디안 차이가있을 수 있습니다.이 매트릭스 클래스에서 유니온의 사용은 완전히 안전합니까?

전 수학 라이브러리에서이 문제가 발생했습니다. 사용하고 있으며 완전히 안전한 사용인지 궁금합니다. 다차원 배열에는 여분의 패딩이 없으며 유형이 두 정의에서 모두 동일하므로 정확히 동일한 양의 메모리를 차지할 것이라고 가정합니다.

template<typename T> class Matrix44T 
{ 
    ... 

    union 
    { 
     T M[16]; 
     T m[4][4]; 
    } m; 
}; 

이 설정에는 단점이 있습니까? 정의의 순서가 어떻게 작동하는지에 차이가 있습니까?

답변

4

나는이 편지에 표준 읽기, 구현에 의존 생각 내 매트릭스 수준에서 동일 할 수 있지만 대부분에서, 노동 조합에서

:

표준 9.5.1를 데이터 중 하나는 회원은 언제든지 활성화 할 수 있습니다. 즉 최대 값이 인 경우 데이터 구성원은 언제든지 노동 조합에 저장 될 수 있습니다. POD-union 에 이 공통 초기 시퀀스 (9.2)를 공유하는 여러 POD 구조체를 포함하는 경우 이 POD- 공용 구조체의 객체가 0이 아닌 경우 유니온을 사용하기 위해 이 보장됩니다. 유형에는 POD 구조체 중 하나 인 이 포함되어 있습니다. POD 구조체 구성원의 공통 시퀀스를 검사 할 수 있습니다. 9.2 참조. ]

문제는 다음 mM주 공통의 초기 시퀀스, 우리는 9.2/15 볼이 답변을 할 수 있습니다 :

두 POD 노조 (9 절) 유형 이다 레이아웃 - 비 정적 데이터 멤버의 수와 동일한 숫자 인 및 해당 비 정적 데이터 멤버의 순서가 임의 인 경우 레이아웃 호환 유형 (3.9)을 사용하는 경우 호환되지 않습니다.이 답을 읽은 후

단어의 엄격한 의미에서, 더 mM가되지 않는 레이아웃 없습니다 호환 될 것으로 보인다.

실제로 이것은 모든 컴파일러에서 정상적으로 작동 할 것이라고 생각합니다.

+0

@ Andreas - 표준 정의에 감사드립니다. 그래서 절대적으로 작동하도록 보장 된 유일한 유형은 동일한 유형의 내용이지만 이름이 다른 두 개의 구조체 일 것입니다. – identitycrisisuk

+0

@identitycrisisuk 한마디 : 예. –

+0

그러나 해결책이 있습니다. * T 형식의 M [0] [0] (즉, m [0] [0]) 포인터를 취하여 M 대신에 포인터를 사용할 수 있습니다. – Ingo

0

아니요. 이것은 가정하에 union을 잘 사용하는 것 같습니다.

mM 이외의 이름을 선택했는데 union의 좋은 사용법은 아닙니다.

+0

가정은 공용체를 사용하는 방법과 아무런 관련이 없습니다. – Ingo

+0

귀하의 가정이 틀린 경우 - 4x4 배열이 16 개 벡터 배열과 크기가 다르면 작동하지 않을 것입니다. – brickner

1

규칙에 따라 게임을 진행하면 패딩 및 엔디안 차이가 발생하지 않습니다. 이 코드

union { int a; float b; } wrong; 

wrong.a = 1; 
printf("%f", wrong.b); 

이것은 당신이 멤버 "A"를 작성한 경우, 다음에서 제외 읽기 "는이"정의되지 않은 때문에 잘못에서

봐.

총계 : 노조가 안전한지 여부는 알 수 없습니다. 안전하지 않은 정의가 아니라 사용 방법입니다.

+1

@Ingo : 기술적으로 나의 예는 정의되지 않은 동작입니까? 최소한 M에 쓰고 m에서 읽으십시오. 누군가 엄격한 컴파일러를 작성했다면 예를 들어 작동하지 않을 것입니다. – identitycrisisuk

+0

@Ingo, 왜 정의되지 않습니까? 공용체가 4 바이트 및 int 배열 인 경우 int로 쓰고 4 바이트로 읽는 것이 합당합니다 (엔디안 고려 사항 포함). 질문과 관련하여 무엇이 있습니까? – brickner

+1

@brickner - 아니요 - 정수는 2 바이트 또는 4 또는 8을 가질 수 있습니다. int가 4 바이트가되어야한다고 말하는 표준을 보여주십시오. (이것은 자바가 아니므로 마음에 들지 않습니다.) – Ingo