호환되지 않는 포인터 할당이 필요하지 않습니다. 2011 년 초안 [초안 N1570] 6.7.2.1 15, "적절하게 변환 된 구조체 객체에 대한 포인터는 초기 멤버를 가리킨다 (또는 그 멤버가 비트 필드이고, 다음에 그것이 상주하는 유닛으로 향한다). 그 반대의 경우 "입니다. 따라서 Derived
의 첫 번째 요소가 Base
개체 인 경우 Derived
에 대한 포인터는 Base
에 대한 포인터로 변환 될 수 있습니다. Derived
의 첫 번째 멤버 인 Base
에 대한 포인터는 Derived
에 대한 포인터로 변환 될 수 있습니다.
이렇게 합법적입니다. 컴파일러는 평소와 다르기 때문에 안전하다고 경고합니다. 명시 적 캐스트를 사용하면이를 방지 할 수 있습니다
p = (Base *) &d;
또는 직접베이스의 주소를 취할 수 있습니다
p = &d.base;
을하지만, 여전히 캐스트가 필요합니다 유래에 다시 자료에서가는 :
Derived *x = (Derived *) p;
첫 번째 멤버가 아닌 다른 곳에베이스를 놓는 경우, 더 불안정합니다. 유도 - 기반 방향은 여전히 쉽습니다. p = &d.base
은 문제가 없습니다.
베이스에 문자 유형 포인터를 가져옵니다 : char *c = (char *) p
당신이 법적 C에 얻을 수있는 다른 방법을 이동하려면이 근접 할 수있다. C에서는 객체에 대한 포인터를 문자 유형에 대한 포인터로 변환하는 것이 합법적이며 객체의 첫 번째 바이트에 대한 포인터를 제공합니다.
Derived
의 시작 부분에서 Base
구성원 인 : c -= offsetof(Derived, base)
으로 바이트 수를 뺍니다. <stddef.h>
을 포함해야합니다.는 Base
의 첫 번째 바이트를 가리키며 Derived
에있는 바이트를 가리키며 Derived
의 바이트를 가리키며 대체로 Derived
을 바이트 배열로 처리 할 수 있도록 허용합니다 (아래 참조). 따라서 빼기 처음으로 돌아갈 수 있습니다. offsetof
매크로는 해당 바이트 수를 제공합니다.
문자 포인터를 Derived
: Derived *x = (Derived *) c
에 대한 포인터로 변환하십시오. 여기, 우리는 흔들리는 땅에있다. Derived
포인터를 문자 포인터로 변환하면 즉시 변환 할 수 있습니다. 그러나 우리는 이런 방식으로 포인터를 얻지 못했습니다. 같은 바이트를 가리키고 있지만 C 표준이 이것을 지원한다는 것이 확실하지 않습니다. (실제로 위의 2 단계는 비슷한 문제가 있는데 객체는 문자 배열로 해석 될 수 있지만 C 표준에서 실제로 지원되는지 확실하지 않은 방향에서 객체를 가져옵니다.함께 이러한 퍼팅
), 변환은 다음과 같습니다 나는로부터 것이 보장되지 않는 한 불확실성 지원을 감안할 때
Derived *x = (Derived *) ((char *) p - offsetof(Derived, base));
, 나는, 단지 실험적인 코드 또는 교실 운동으로 사용할 것 C 구현이 포인터 연산이 지원된다는 것을 사용하고있었습니다. 첫 번째 요소로 받침대를 사용하는 것이 좋습니다. 이러한 변환은 엄격하게 C를 준수합니다.