2016-09-20 3 views
4

그때 나는 이와 같은 지금은 기능이 이러한 유형의구조체의 정렬 및 유형 재 해석

struct Pair{ 
    A a; 
    B b; 
}; 

을 나는 두 가지 유형 A와

B.

이 있다고 할 수 있습니다.

void function(Pair& pair); 

그리고 function은 오직 한 쌍의 a 부분을 사용한다고 가정 할 수 있습니다.

그런 다음이 방법으로 함수를 사용하고 호출하려면 정의되지 않은 동작입니까?

A a; 
function(reinterpret_cast<Pair&>(a)); 

나는 컴파일러가 구성원 후 패딩 바이트를 삽입 할 수 있지만 또한 첫 번째 멤버 전에 할 수 있다는 것을 알고?

+3

함수가 'A'부분에만 액세스하는 경우 'A'입력 대신 'Pair' 입력을받는 이유는 무엇입니까? –

+0

사실이 예제는 제 질문을 설명하기 위해 일반적인 것입니다. 이것이 정의되지 않았는지 알고 싶습니다. 그러나 일련의 일반 동작을 구현하고 동일한 서명이 있어야하는 함수 집합의 일부라고 가정 해 보겠습니다. – user183833

+1

관련 항목 : http://stackoverflow.com/questions/15994237/how-is-is-standard-layout-useful – Mysticial

답변

4

나는 행동을 정의했다고 생각하는데, Pair은 표준 레이아웃이라고 가정합니다. 그렇지 않으면 정의되지 않은 동작입니다.

먼저 표준 레이아웃 클래스와 첫 번째 멤버는 주소를 공유합니다. (이전에 규칙을 명확히) basic.compound]의 새로운 표현 읽

두 개체및 B 포인터 상호 전환 경우 :
* [...]
하나는 표준 레이아웃 클래스 객체이고 다른 하나는 해당 객체의 첫 번째 비 정적 데이터 멤버입니다. 또는 [...]
* [...]
두 객체가 인 경우 포인터 상호 변환 가능 n 그들은 동일한 주소를 가지고 있으며, reinterpret_cast (5.2.10)을 통해 포인터에서 다른 포인터로 포인터 을 얻을 수 있습니다. [class.mem]에서도

: 표준 레이아웃 클래스 객체가 아닌 정적 데이터 멤버가

경우, 그 주소가 주소와 동일한 첫 비 정적 데이터 회원. 그렇지 않으면 그 주소는 첫 번째 기본 클래스 하위 객체 (있는 경우)의 주소와 같습니다.

reinterpret_castA에서 Pair까지입니다. functiona 개체에만 액세스하면 A의 오프셋이 0이므로 해당 액세스가 잘 정의되어 있으므로 functionA&이되는 것과 같습니다. b에 대한 액세스는 분명히 정의되지 않습니다.그러나


, 나는 코드가 동작을 정의 생각하면서, 그것은 잘못된 생각이다. 정의 된 동작은 입니다. 현재는이지만 누군가 언젠가는 function을 변경하여 pair.b을 참조하면 고통의 세계에 빠지게됩니다.

void function(A& a) { ... } 
void function(Pair& p) { function(p.a); } 

과 당신의 a 직접 function 전화 : 그것은 쉽게 많은 간단하게 작성하는 것입니다.

+0

먼저 답변 해 주셔서 감사합니다. 표준 레이아웃 클래스에 대한 읽기 표준 레이아웃을 가진 클래스의 경우 모든 멤버가 동일한 액세스 제어 권한을 가져야한다는 것을 알았습니다. 페어가 예를 들어 제 3의 사적인 멤버를 가졌다면 무엇이 바뀔지도 모르고 어쩌면 바뀔지도 모릅니다. 컴파일러가 순서를 변경하는 이유는 무엇입니까? – user183833

+0

@ user183833 POD (표준 레이아웃의 선구자)는 [tag : C]와의 호환성을위한 것입니다. C++ 특정 구문을 사용하는 코드는 선택한 방식으로 구조체 레이아웃을 뒤죽박죽으로 사용할 수있었습니다. 개인 정보를 먼저 또는 마지막으로 또는 중간에 넣을 수 있습니다. 개인 데이터를 별도의 메모리 공간에 저장할 수도 있다고 생각하지만 확실하지 않습니다. POD가 표준 레이아웃으로 발전했을 때 몇 가지 요구 사항이 제거되었을 때 : 모든 컴파일러는 이미 생성자를 사용하여 POD를 만들었으므로 기존 레이아웃을 유용한 방식으로 코드화 할 수 있습니다. – Yakk

+0

@ Barry 마지막으로 말했듯이 말입니다. [Here] (http://stackoverflow.com/questions/39601838/implementing-a-hashmap-using-a-hashtable-implementation)은 유스 케이스이다. – user183833

-1

예, 정의되지 않은 동작입니다.

구조체 쌍에서 a와 b 사이에 패딩이있을 수 있습니다. 구조체 멤버에 대한 할당은 구조체의 모든 패딩을 수정할 수 있습니다. 따라서 pair.a에 대한 할당은 구조체에 패딩이 있다고 생각하는 메모리를 수정할 수 있습니다. 실제로는 사용자가 차지하는 메모리 다음에 임의의 메모리가 있습니다.

+1

답변 해 주셔서 감사합니다. 한 가지 방법으로 객체에 대한 할당이 그 객체 외부의 바이트를 수정할 수 있습니까? 어떻게 그리고 왜 일어날까요? – user183833