문제

나는 이해 reinterpret_cast 위험합니다. 나는 단지 그것을 테스트하기 위해 이것을하고 있습니다. 다음 코드가 있습니다.

int x = 0;
double y = reinterpret_cast<double>(x);

프로그램을 컴파일하려고하면 오류가 발생합니다.

유형 'float'에서 type 'double에서 유효하지 않은 캐스트

무슨 일이야? 나는 생각했다 reinterpret_cast 사과를 잠수함으로 변환하는 데 사용할 수있는 도적 캐스트는 왜 간단한 캐스트 컴파일이 아닌가?

도움이 되었습니까?

해결책

캐스트가 반환 한 값에 Y를 할당함으로써 실제로 값을 캐스팅하지 않습니다. x, 당신은 그것을 변환하고 있습니다. 그건, y 지적하지 않습니다 x 그리고 그것이 부유물을 가리키는 척합니다. 변환은 새로운 유형의 값을 구성합니다 float 값을 할당합니다 x. C ++ 에서이 변환을 수행하는 몇 가지 방법이 있습니다.

int main()
{
    int x = 42;
    float f = static_cast<float>(x);
    float f2 = (float)x;
    float f3 = float(x);
    float f4 = x;
    return 0;
}

유일한 차이는 마지막으로 (암시 적 변환) 더 높은 경고 수준에서 컴파일러 진단을 생성하는 것입니다. 그러나 그들은 모두 기능적으로 똑같은 일을합니다. 그리고 많은 경우 실제로 동일한 기계 코드에서와 같은 것.

이제 당신이 정말로 척하고 싶다면 x 플로트입니다. 그러면 당신은 정말로 캐스팅하고 싶어합니다 x, 이렇게함으로써 :

#include <iostream>
using namespace std;

int main()
{
    int x = 42;
    float* pf = reinterpret_cast<float*>(&x);
    (*pf)++;
    cout << *pf;
    return 0;
}

이것이 얼마나 위험한 지 알 수 있습니다. 사실, 내 컴퓨터에서 이것을 실행할 때의 출력은 1, 이것은 확실히 42+1이 아닙니다.

다른 팁

C ++에서 reinterpret_cast 언어 사양에 명시 적으로 나열된 특정 변환 세트 만 수행 할 수 있습니다. 요컨대, reinterpret_cast 포인터-포인터 변환 및 참조-참조 전환 (포인터 투 인트거 및 정수-포인터 변환) 만 수행 할 수 있습니다. 이것은 캐스트의 이름으로 표현 된 의도와 일치합니다. 포인터/참조 재 해석에 사용되도록 의도됩니다.

당신이하려는 것은 재 해석이 아닙니다. an int A로 double 참조 유형으로 변환해야합니다

double y = reinterpret_cast<double&>(x); 

동등한 포인터 기반 재 해석은 아마도 더 명백 할 것입니다

double y = *reinterpret_cast<double*>(&x); // same as above

그러나 그 정도에 주목하십시오 reinterpret_cast 참조/포인터 유형을 변환 할 수 있습니다. 결과 참조/포인터를 통해 데이터를 읽으려는 실제 시도는 정의되지 않은 동작을 생성합니다.

그리고 어쨌든 이것은 물론 플랫폼에서 큰 의미가 없습니다. int 그리고 double 크기가 다릅니다 (더 큰 경우 double 당신은 점령 한 기억 너머를 읽습니다 x).

그래서 결국 그것은 당신이 달성하려는 것들로 요약됩니다. 메모리 재 해석? 위 참조. 어떤 종류의 더 의미가 있습니다 int 에게 double 변환? 그렇다면, reinterpret_cast 여기서 당신을 도와주지 않을 것입니다.

reinterpret_cast는 일반적인 캐스트가 아닙니다. C ++ 03 사양에 따르면 섹션 5.2.10.1 :

ReneterPret_cast를 사용하여 명시 적으로 수행 할 수있는 변환은 아래에 나열되어 있습니다. ReneterPret_cast를 사용하여 명시 적으로 다른 변환을 수행 할 수 없습니다.

그리고 적분과 부동 소수점 유형 사이에서 변환하는 것을 설명하는 내용은 없습니다 (또는 적분 유형 사이에서도 불법입니다. reinterpret_cast<long>(int(3));)

당신이 당신의 비트를 변환하려는 경우 int A의 표현에 double, 당신은 캐스팅해야합니다 주소 가치가 아닙니다. 또한 크기와 일치해야합니다.

uint64_t x = 0x4045000000000000;
double y = *reinterpret_cast<double *>(&x);

컴파일러는 넌센스로 쓴 내용을 거부합니다 int 그리고 double 크기가 다른 개체 일 수 있습니다. 확실히 위험하지만 이런 식으로 동일한 효과를 얻을 수 있습니다.

int x = 0;
double y = *reinterpret_cast<double*>(&x);

이는 경우에도 위험합니다 x 그리고 y 다른 크기입니다 (가정 해 봅시다 int 4 바이트이고 double 8 바이트입니다. &x 채우기 위해 y 4 바이트에 액세스합니다 x 그리고 4 바이트의 ... 다음에 기억에 나오는 것 (아마도 시작 y, 또는 쓰레기 또는 다른 것들.)

정수를 더블로 변환하려면 static_cast 그리고 그것은 변환을 수행 할 것입니다.

비트 패턴에 액세스하려면 x, 편리한 포인터 유형 (예 : byte*) 및 접근 sizeof(int) / sizeof(byte):

byte* p = reinterpret_cast<byte*>(&x);
for (size_t i = 0; i < sizeof(int); i++) {
  // do something with p[i]
}

RENETERPRET CAST를 사용하면 메모리 블록을 다른 유형으로 재 해석 할 수 있습니다. 이것은 포인터에서 수행되어야합니다 또는 참조:

int x = 1;
float & f = reinterpret_cast<float&>(x);
assert( static_cast<float>(x) != f );   // !!

또 다른 것은 사실이 매우 위험한 캐스트라는 것입니다. 결과로 이상한 값이 나오거나 위의 주장이 실패하지 않을뿐만 아니라 유형이 크기가 다르고 '소스'에서 '소스'에서 재 해석되기 때문입니다. '대상'유형, 재 해석 된 참조/포인터의 모든 작업이 액세스됩니다. sizeof(destination) 바이트. 만약에 sizeof(destination)>sizeof(source) 그러면 실제 변수 메모리를 넘어서서 응용 프로그램을 죽이거나 소스 또는 대상 이외의 다른 변수를 덮어 쓰는 것입니다.

struct test {
   int x;
   int y;
};
test t = { 10, 20 };
double & d = reinterpret_cast<double&>( t.x );
d = 1.0/3.0;
assert( t.x != 10 ); // most probably at least.
asswet( t.y != 20 );

reinterpret_cast 포인터에 가장 잘 사용됩니다. 따라서 하나의 물체에 대한 포인터는 "잠수함"으로 바꿀 수 있습니다.

에서 MSDN:

RenterPret_cast 연산자는 본질적으로 안전하지 않은 char* to int* 또는 One_class*와 같은 전환에 사용할 수 있습니다.

RenterPret_cast의 결과는 원래 유형으로 다시 캐스트되는 것 외에는 안전하게 사용할 수 없습니다. 다른 용도는 기껏해야 할 수 없습니다.

재 해석 접근 방식은 불완전한 결과로 이상한 경로를 이끌었습니다. 결국 나는 이렇게 memcpy가 훨씬 낫다는 것을 알았습니다!

double source = 0.0;
uint64_t dest;
memcpy(&dest, &source, sizeof(dest));

int를 더블로 캐스트하는 것은 캐스트가 필요하지 않습니다. 컴파일러는 암시 적으로 할당을 수행합니다.

reinterpret_cast는 포인터와 참조와 함께 사용됩니다. int * a double *.

그 흥미 롭군요. 어쩌면 캐스트가 두 배로 시도되기 전에 Int에서 Float로 암시적인 변환을 수행 할 수 있습니다. INT 및 플로트 유형은 바이트에서 크기가 같은 경향이 있습니다 (물론 시스템에 따라 다름).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top