void *를 무엇이든 캐스팅 할 때 static_cast 또는 reinterpret_cast를 사용해야합니까?


202

static_cast와 reinterpret_cast는 모두 void *를 다른 포인터 유형으로 캐스팅하는 데 잘 작동하는 것 같습니다. 다른 것을 선호하는 좋은 이유가 있습니까?


78
@anon 분명히 POSIX 스레드를 사용한 적이 없었습니다.
user470379

7
@ user470379 와우 ... 그래서 내가이 질문에 착륙 한 바로 그 이유입니다! 훌륭한 관찰 :-).
오우거 시편 33

답변:


148

사용static_cast : 여기에서 어떤 변환이 이루어 졌는지 정확하게 설명하는 가장 좁은 캐스트입니다.

reinterpret_cast"타입 안전성을 완전히 무시하고 A에서 B로 캐스트"한다는 의미이므로 사용 하는 것이 더 적합 하다는 오해 가 있습니다.

그러나 이것은 실제로의 효과를 설명하지는 않습니다 reinterpret_cast. 그보다 reinterpret_cast는 여러 가지 의미를 지니고 있으며, 그 의미는 모두 "에 의해 수행되는 매핑 reinterpret_cast이 구현 정의되어있다"는 것입니다. [5.2.10.3]

그러나에서 주조의 특정 경우 void*T*매핑 완전히 표준에 의해 잘 정의입니다; 즉, 주소를 변경하지 않고 유형이없는 포인터에 유형을 지정합니다.

이것이 선호하는 이유 static_cast입니다.

또한, 더 중요한 것은 모든 사용이 reinterpret_cast실제로 (포인터를 위해) 다른 것으로 변환하기 때문에 매우 위험 하다는 사실 이며, static_cast훨씬 더 제한적이므로 더 나은 보호 수준을 제공합니다. 이것은 실수로 한 포인터 유형을 다른 포인터 유형으로 강제 변환하려고했던 버그에서 이미 나를 구해 냈습니다.


8

이것은 어려운 질문입니다. 한편, Konrad는 reinterpret_cast 의 스펙 정의에 대해 훌륭한 지적을하고 있지만 실제로는 아마 같은 일을합니다. 반면, 포인터 유형 사이를 캐스팅하는 경우 (예를 들어 char *를 통해 메모리에서 인덱싱 할 때 일반적으로 발생하는 것처럼) static_cast 는 컴파일러 오류를 생성하고 어쨌든 reinterpret_cast 를 사용해야 합니다.

실제로 는 캐스트 작업의 의도를 더 설명하기 때문에 reinterpret_cast를 사용 합니다. 다른 연산자가 포인터 재 해석만을 지정하는 경우를 확실히 만들 수는 있지만 동일한 주소가 반환되도록 보장하지만 표준에는 없습니다.


6
" 포인터 재 지정 만 지정하는 다른 연산자 (동일한 주소가 반환되도록 보장) "포옹? 그 연산자 reinterpret_cast !
curiousguy

2
@curiousguy 표준에 따르면 사실이 아닙니다. reinterpret_cast는 동일한 주소 사용을 보장하지 않습니다. 한 유형에서 다른 유형으로 reinterpret_cast 를 다시 한 번 다시 되 돌리면 시작한 주소와 같은 주소로 돌아갑니다.
ClydeTheGhost

0

항상 가장 약한 캐스트를 사용하는 것이 좋습니다.

reinterpret_cast에 대한 포인터를 캐스팅하는 데 사용될 수 있습니다 float. 캐스트의 구조가 깨질수록 더 많은주의가 필요합니다.

의 경우 char*c 스타일 캐스트를 사용 reinterpret_pointer_cast합니다.


2
" reinterpret_cast를 사용하여 포인터를 float에 캐스트 할 수 있습니다. "확실하지 않습니다!
curiousguy

3
아마float f = *reinterpret_cast<const float*>(&p);
벤 Voigt

2
@BenVoigt 포인터 사이에 캐스팅됩니다. 그중 하나는 부동 포인터였습니다.
nodakai 2016 년

5
@BenVoigt "전체 표현"은 캐스트가 아닙니다. 이 표현은 캐스트에 적용된 역 참조로 구성됩니다. 에 대한 포인터를 캐스트 할 수 있다고 주장했는데 float, 이는 거짓입니다. 표현 캐스트 void **const float *다음과 변환, 참조 취소 조작을 (캐스트가되지 않는) 사용 const float *float.
MM

2
당신이 요청하는 사람에 대한 응답으로 그 코드를 제공 @BenVoigt 사람이 포인터 사이의 코드 캐스트 (는 않습니다), 당신이 말한 것을 말할 때 다음, 그리고 "어떻게 ... 캐스팅 할" "아니"
MM

-7

내 개인적인 취향은 다음과 같은 코드 활용 능력을 기반으로합니다.

void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();

또는

typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();

둘 다 결국 동일하지만 static_cast는 미들웨어, 앱 환경에서 더 적합 해 보이지만, 캐스트 재 해석은 하위 수준 라이브러리 IMHO에서 볼 수있는 것과 비슷합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.