2015-02-07 7 views
7

는 문자 배열입니다 저장된 객체를 가져 오는 것 :reinterpret_cast/static_cast 나는 원시 스토리지에서 일하고 있어요 변형 클래스에서 정의되지 않은 동작

template<class X> 
const X &get() 
{ 
    // ... 
    return *reinterpret_cast<X *>(storage); 
    // ... 
} 

작동하는 것처럼 보이지만 항상 잘 정의되어 있습니까? 포인터를 역 참조하는 것이 걱정됩니다 (형식 앨리어싱 규칙에 의해 허용됩니까?).

https://stackoverflow.com/a/7321815/3235496 (James Kanze 님의 댓글 참조)

는 현재 구현 및

return *static_cast<const X *>(static_cast<const void *>(storage)); 

관련 질문/대답 사이가 어떤 차이가 있습니까. 문제가 발생할 수있는 곳 storage으로 C++ When should we prefer to use a two chained static_cast over reinterpret_cast

+0

확실하게이'new (storage) X (x);'는 메모리 누수입니다. –

+1

@EdHeal 그것은 새로운 배치를 통해 저장소에 X를 만듭니다. 정렬 된 저장소의 경우 반드시 안전한 방법이어야합니다 (예 : http://stackoverflow.com/questions/4583125/char-array-as-storage-for- placement-new). 세부 사항을 추가 할 수 있습니까? – manlio

답변

4

가 올바르게 정렬되어, 내가 상상할 수 없다 :


편집

두 번째 질문은 이미 여기에 답이 있습니다. 포인터 변환에 대한 단락 (*) 4.10의 의미는 다음과 같습니다. "cv T에 대한 포인터"유형의 prvalue는 T가 객체 유형 인 경우 "포인터를 cv void에 대한 포인터"유형의 prvalue로 변환 할 수 있습니다. 오브젝트 유형에 대한 포인터의 널 (NULL)이 아닌 포인터 값을 "cv void에 대한 포인터"로 변환 한 결과는 원래 포인터 값과 같은 메모리의 주소를 나타냅니다.

두 번째 질문에 대해서는 5.2.10 reinterpres_cast에 있습니다. 개체 포인터를 다른 형식의 개체 포인터로 명시 적으로 변환 할 수 있습니다. 객체 포인터 유형의 prvalue v가 객체 포인터 유형 "cv T 포인터"로 변환 될 때 결과는 static_cast<cv T*>(static_cast<cv void*>(v))이고 cv은 선택 사항 인 const 또는 volatile을 나타냅니다.

이 부분은 사양별로 보장됩니다. 우리가 void *에 캐스팅 메모리의 첫 번째 바이트를 가리해야한다는 것을보고 더 많은 표준 ... 제공하는 컴파일러에 대한 이해에 대한 UB는 같은 이해 ;-)

(*) 참조가있다 없다 : Draft for current C++ specification