reinterpret_cast는 언제 사용합니까?


459

reinterpret_castvs 의 적용 가능성과 혼동되지 않습니다 static_cast. 내가 읽은 일반적인 규칙에서 컴파일 타임에 유형을 해석 할 수있을 때 정적 캐스트를 사용하는 것이 단어 static입니다. 이것은 C ++ 컴파일러가 암시 적 캐스트에도 내부적으로 사용하는 캐스트입니다.

reinterpret_cast두 가지 시나리오에 적용 할 수 있습니다.

  • 정수 유형을 포인터 유형으로 변환하거나 그 반대로 변환
  • 한 포인터 유형을 다른 포인터 유형으로 변환하십시오. 내가 얻는 일반적인 아이디어는 이것이 이식 불가능하며 피해야한다는 것입니다.

내가 약간 혼란스러워하는 곳에서 필요한 사용법 중 하나는 C에서 C ++을 호출하고 C 코드는 C ++ 객체를 잡아야하므로 기본적으로을 보유하고 void*있습니다. void *클래스 유형과 클래스 유형 을 변환하려면 어떤 캐스트를 사용해야 합니까?

난 둘의 사용 본 static_cast과를 reinterpret_cast? 내가 읽은 것에서 static컴파일 타임에 캐스트가 발생할 수 있기 때문에 더 나은 것처럼 보입니까? reinterpret_cast한 포인터 유형에서 다른 포인터 유형으로 변환하는 데 사용한다고 말하고 있습니까?


9
reinterpret_cast런타임에는 발생하지 않습니다. 둘 다 컴파일 타임 문입니다. 에서 en.cppreference.com/w/cpp/language/reinterpret_cast : "달리 static_cast 만에 const_cast처럼 reinterpret_cast 표현은 CPU의 지시에 컴파일되지 않습니다 그것은 순전히 비트의 순서를 처리하도록 컴파일러에 지시 컴파일러 지시어입니다. "new_type 유형 인 것처럼 표현식의 (객체 표현)"
Cris Luengo

@HeretoLearn, * .c 및 * .cpp 파일에서 관련 코드 조각을 추가 할 수 있습니까? 나는 그것이 질문의 설명을 향상시킬 수 있다고 생각합니다.
OrenIshShalom

답변:


442

C ++ 표준은 다음을 보장합니다.

static_castvoid*주소 를 유지하려면 주소 를 유지하십시오. 즉, 다음에,이다 a, b그리고 c같은 주소에 대한 모든 점 :

int* a = new int();
void* b = static_cast<void*>(a);
int* c = static_cast<int*>(b);

reinterpret_cast다른 유형에 대한 포인터를 캐스트 한 다음 reinterpret_cast원래 유형으로 되 돌리면 원래 값을 얻습니다. 따라서 다음에서 :

int* a = new int();
void* b = reinterpret_cast<void*>(a);
int* c = reinterpret_cast<int*>(b);

ac같은 값을 포함하지만,의 값은 b지정되지 않습니다. (실제로는 일반적으로 같은 주소를 포함 a하고 c있지만, 표준에 명시되지 않은 것, 그리고 더 복잡한 메모리 시스템과 시스템에 진실하지 않을 수 있습니다.)

과에서 주조를 들어 void*, static_cast선호한다.


18
나는 'b'가 정의되지 않았다는 사실을 좋아합니다. 그것은 당신이 그것으로 바보 같은 일을 중지합니다. 다른 포인터 유형으로 무언가를 캐스팅하면 문제가 발생하고 의존 할 수 없다는 사실이 더 조심스럽게 만듭니다. 위에서 static_cast <>를 사용했다면 어쨌든 'b'는 무엇입니까?
Martin York

3
reinterpret_cast <>는 동일한 비트 패턴을 보장한다고 생각했습니다. (다른 유형에 대한 유효한 포인터와 동일하지 않음).
Martin York

37
b사용할 때 C ++ 11에서 더 이상 값을 지정하지 않았습니다 reinterpret_cast. 그리고 C ++ 03에서는 int*to 의 캐스트를 수행 하는 void*것이 금지되었습니다 reinterpret_cast(컴파일러는 그것을 구현하지 않았지만 실용적이지 않았으므로 C ++ 11로 변경되었습니다).
요하네스 샤 우브-litb

55
이것은 실제로 "reinterpret_cast를 사용할 때"의 질문에 대답하지 않습니다.
einpoklum

6
@LokiAstari 나는 불특정이 바보 같은 일을 저 지르지 않는다고 생각합니다. 그것은 당신이 지정되지 않은 것을 기억할 때만 당신을 멈 춥니 다. 큰 차이. 개인적으로 나는 불특정을 좋아하지 않습니다. 기억해야 할 것이 너무 많습니다.
Helin Wang

158

reinterpret_cast불투명 한 데이터 유형과 인터페이스 할 때 필요한 경우 가 있습니다. 프로그래머가 제어 할 수없는 공급 업체 API에서 자주 발생합니다. 다음은 공급 업체가 임의의 전역 데이터를 저장하고 검색하기위한 API를 제공하는 고안된 예입니다.

// vendor.hpp
typedef struct _Opaque * VendorGlobalUserData;
void VendorSetUserData(VendorGlobalUserData p);
VendorGlobalUserData VendorGetUserData();

이 API를 사용하려면 프로그래머가 데이터를 VendorGlobalUserData다시 캐스팅해야 합니다. static_cast작동하지 않으므로 reinterpret_cast다음을 사용해야합니다 .

// main.cpp
#include "vendor.hpp"
#include <iostream>
using namespace std;

struct MyUserData {
    MyUserData() : m(42) {}
    int m;
};

int main() {
    MyUserData u;

        // store global data
    VendorGlobalUserData d1;
//  d1 = &u;                                          // compile error
//  d1 = static_cast<VendorGlobalUserData>(&u);       // compile error
    d1 = reinterpret_cast<VendorGlobalUserData>(&u);  // ok
    VendorSetUserData(d1);

        // do other stuff...

        // retrieve global data
    VendorGlobalUserData d2 = VendorGetUserData();
    MyUserData * p = 0;
//  p = d2;                                           // compile error
//  p = static_cast<MyUserData *>(d2);                // compile error
    p = reinterpret_cast<MyUserData *>(d2);           // ok

    if (p) { cout << p->m << endl; }
    return 0;
}

다음은 샘플 API를 구현 한 것입니다.

// vendor.cpp
static VendorGlobalUserData g = 0;
void VendorSetUserData(VendorGlobalUserData p) { g = p; }
VendorGlobalUserData VendorGetUserData() { return g; }

7
그래, 그것은 내가 생각할 수있는 reinterpret_cast의 유일한 의미있는 사용에 관한 것입니다.
jalf

8
이것은 늦은 질문 일 수 있지만 공급 업체 API가 왜 그것을 사용하지 void*않습니까?
Xeo

19
@Xeo void *를 사용하지 않습니다. 컴파일 타임에 (일부) 유형 검사가 손실되기 때문입니다.
jesup

4
"불투명 한"데이터 유형의 실제 사용 사례는 API를 C에 노출하지만 구현을 C ++로 작성하려는 경우입니다. ICU는 여러 곳에서이 작업을 수행하는 라이브러리의 예입니다. 예를 들어, 스푸핑 검사기 API, 당신은 유형의 포인터를 처리 USpoofChecker*, USpoofChecker빈 구조체이다. 당신이 통과 할 때마다 그러나, 후드, USpoofChecker*그것은 거쳐 reinterpret_cast내부 C ++ 유형.
sffc

@ sffc 왜 C 구조체 유형을 사용자에게 노출시키지 않습니까?
Gupta

101

짧은 대답 : 당신이 무엇을 reinterpret_cast의미 하는지 모른다면 그것을 사용하지 마십시오. 나중에 필요할 경우 알 것입니다.

전체 답변 :

기본 숫자 유형을 고려해 봅시다.

int(12)를 들어 unsigned float (12.0f)프로세서 로 변환 할 때 두 숫자의 비트 표현이 다르기 때문에 일부 계산을 호출해야합니다. 이것이 static_cast의미 하는 바입니다.

반면에 reinterpret_castCPU를 호출하면 계산이 호출되지 않습니다. 메모리에있는 비트 세트를 다른 유형이있는 것처럼 처리합니다. 당신이 변환 할 때 그래서 int*float*이 키워드와 함께, (포인터 dereferecing 후) 새 값은 수학적 의미에서 이전 값과는 아무 상관이 없습니다.

예 :reinterpret_cast 바이트 순서 (엔디안)라는 한 가지 이유로 인해 이식성이없는것은 사실입니다. 그러나 이것은 놀랍게도 그것을 사용하는 가장 좋은 이유입니다. 예를 상상해 봅시다 : 파일에서 이진 32 비트 숫자를 읽어야하며, 그것이 빅 엔디안이라는 것을 알고 있습니다. 코드는 일반적이어야하며 빅 엔디안 (예 : 일부 ARM) 및 리틀 엔디안 (예 : x86) 시스템에서 제대로 작동합니다. 따라서 바이트 순서를 확인해야합니다. 당신이 쓸 수 있도록 컴파일 시간에 잘 알려진 constexpr기능 : 당신은이를 달성하기 위해 함수를 작성할 수 있습니다 :

/*constexpr*/ bool is_little_endian() {
  std::uint16_t x=0x0001;
  auto p = reinterpret_cast<std::uint8_t*>(&x);
  return *p != 0;
}

설명 :x 메모리에서이진 표현은0000'0000'0000'0001(큰) 또는0000'0001'0000'0000(little 엔디안) 일 수 있습니다. 재 해석 캐스팅 후p포인터아래의 바이트는각각0000'0000또는0000'0001입니다. 정적 캐스팅을 사용하는 경우0000'0001어떤 엔디안 (endianness)을 사용하든항상그렇습니다.

편집하다:

첫 번째 버전에서는 예제 함수 is_little_endian를로 만들었습니다 constexpr. 최신 gcc (8.3.0)에서 잘 컴파일되지만 표준에 따르면 불법입니다. clang 컴파일러는 컴파일을 거부합니다 (정확합니다).


1
좋은 예입니다! 나는 uint16_t를 짧게 바꾸고 uint8_t를 unsigned char로 바꾸면 사람이 덜 모호하게 만듭니다.
Jan Turoň

@ JanTuroň true, short메모리에서 16 비트 가 필요 하다고 가정 할 수 없습니다 . 수정했습니다.
jaskmar

1
예가 잘못되었습니다. reinterpret_cast는 constexpr 함수에서 허용되지 않습니다
Michael Veksler

1
우선이 코드는 최신 clang (7.0.0)과 gcc (8.2.0)에 의해 거부됩니다. 불행히도 나는 공식 언어의 한계를 찾지 못했습니다. 내가 찾을 수있는 것은 social.msdn.microsoft.com/Forums/vstudio/en-US/…였습니다.
Michael Veksler

2
보다 구체적으로, en.cppreference.com/w/cpp/language/constant_expression (항목 16)은 reinterpret_cast를 상수 표현식에 사용할 수 없음을 분명히 나타냅니다. 또한 볼 github.com/cplusplus/draft/blob/master/papers/N3797.pdf 명시 적으로 reinterpret_cast 배제 (5.19 상수 식) pages125-126. 그런 다음 7.1.5 constexpr 지정자 항목 5 (146 페이지) * 템플릿이 아닌 기본이 아닌 constexpr 함수의 경우 ... 인수 값이 존재하지 않는 경우 ... 핵심 상수 표현식의 하위 표현식이 평가 될 수 있습니다 (5.19). ), 프로그램이 잘못 형성된다 *
마이클 Veksler

20

의 의미 reinterpret_cast는 C ++ 표준에 의해 정의되지 않습니다. 따라서 이론적으로 reinterpret_cast는 프로그램을 중단시킬 수 있습니다. 실제로 컴파일러는 예상 한 것을 수행하려고 시도합니다. 즉, 전달하는 비트를 마치 캐스팅하려는 유형 인 것처럼 해석합니다. 사용할 컴파일러가 무엇인지 알고 있다면 reinterpret_cast 그것을 사용할 수 있지만 이식성 이 있다고 말하는 것은 거짓말 일 것입니다.

당신이 묘사하는 경우와 고려할 수있는 거의 모든 경우 대신에 다른 대안을 reinterpret_cast사용할 수 있습니다 static_cast. 무엇보다도 표준은 기대할 수있는 것에 대해 말하고 있습니다 static_cast(§5.2.9).

“pointer to cv void”유형의 rvalue는 객체 유형에 대한 포인터로 명시 적으로 변환 될 수 있습니다. "포인터에서 cv void 로의 포인터"로 변환 된 객체에 대한 포인터 유형의 값은 원래 포인터 유형으로 돌아갑니다.

따라서 유스 케이스의 경우 표준화위원회가 귀하가 사용하도록 의도 한 것이 분명해 보입니다 static_cast.


5
프로그램이 완전히 충돌하지는 않습니다. 이 표준은 reinterpret_cast에 대한 몇 가지 보증을 제공합니다. 사람들이 자주 기대하는만큼 많지 않습니다.
jalf

1
제대로 사용하면 안됩니다. 즉, A에서 B로 A로 reinterpret_cast는 완벽하게 안전하고 잘 정의되어 있습니다. 그러나 B의 가치는 명시되지 않았으며, 네가 그것에 의존한다면 나쁜 일이 일어날 수 있습니다. 그러나 캐스트 자체는 표준에서 허용하는 방식으로 만 사용하는 한 충분히 안전합니다. ;)
jalf

55
lol, reinterpret_crash가 실제로 프로그램을 손상시킬 수 있다고 생각합니다. 그러나 reinterpret_cast는 그렇지 않습니다. ;)
jalf 2012

5
<irony> 컴파일러에서 시도했지만 컴파일을 거부했습니다 reinterpret_crash. 컴파일러 버그로 인해 재 해석 프로그램이 중단되는 것을 막을 수는 없습니다. 최대한 빨리 버그를 신고하겠습니다! </ irony>
paercebal

18
@paercebaltemplate<class T, U> T reinterpret_crash(U a) { return *(T*)nullptr; }

12

reinterpret_cast의 한 가지 사용법은 비트 연산을 (IEEE 754) 부동 소수점에 적용하려는 경우입니다. 이에 대한 한 가지 예는 Fast Inverse Square-Root 트릭입니다.

https://ko.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code

float의 이진 표현을 정수로 취급하고 오른쪽으로 이동하여 상수에서 빼서 지수를 반으로 줄입니다. float로 다시 변환 한 후에는이 근사값을 더 정확하게하기 위해 Newton-Raphson 반복이 적용됩니다.

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                       // evil floating point bit level hacking
    i  = 0x5f3759df - ( i >> 1 );               // what the deuce? 
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

    return y;
}

원래 C로 작성되었으므로 C 캐스트를 사용하지만 유사한 C ++ 캐스트는 reinterpret_cast입니다.


1
error: invalid cast of an rvalue expression of type 'int64_t {aka long long int}' to type 'double&' reinterpret_cast<double&>((reinterpret_cast<int64_t&>(d) >> 1) + (1L << 61))- ideone.com/6S4ijc
Orwellophile

1
표준은 이것이 정의되지 않은 동작이라고 말합니다. en.cppreference.com/w/cpp/language/reinterpret_cast ( "유형 앨리어싱"아래)
Cris Luengo

@CrisLuengo을 모두 reinterpret_cast로 대체 memcpy해도 여전히 UB입니까?
sandthorn

@sandthorn : 이것은 표준에 따른 UB이지만 아키텍처에 적합하다면 걱정하지 마십시오. 이 트릭은 인텔 아키텍처의 모든 컴파일러에 적합합니다. 다른 아키텍처에서는 의도 된대로 작동하지 않거나 충돌 할 수 없습니다. 예를 들어 플로트와 롱은 별도의 메모리 구획에 저장 될 수 있습니다 (아키텍처는 알지 못하지만 단지 논쟁의 여지가 있습니다 ...) . memcpy확실히 합법적으로 만들 것입니다.
Cris Luengo


2
template <class outType, class inType>
outType safe_cast(inType pointer)
{
    void* temp = static_cast<void*>(pointer);
    return static_cast<outType>(temp);
}

템플릿을 사용하여 간단한 안전한 캐스트를 작성하고 작성했습니다. 이 솔루션은 함수에 포인터를 캐스트한다고 보장하지 않습니다.


1
뭐? 왜 귀찮게? "이것은 reinterpret_cast이미이 상황에서 이미 하고있는 일이다 :"객체 포인터는 다른 유형의 객체 포인터로 명시 적으로 변환 될 수있다. [72] 객체 포인터 유형 의 prvalue v 가 객체 포인터 유형 "pointer to cv T " 로 변환 될 때 , 결과는 static_cast<cv T*>(static_cast<cv void*>(v))입니다. " -N3797.
underscore_d

에 관해서는 c++2003표준 I는 할 수 없습니다 것을 찾을 reinterpret_cast않습니다static_cast<cv T*>(static_cast<cv void*>(v))
사샤 Zezulinsky

1
좋습니다. 그러나 13 년 전의 버전에 대해서는 신경 쓰지 않으며 대부분의 코더가 피할 수 있다면 그렇게하지 않아야합니다. 답변과 의견은 달리 명시되지 않는 한 실제로 사용 가능한 최신 표준을 반영해야합니다 ... IMHO. 어쨌든,위원회는 2003 년 이후에 이것을 명시 적으로 추가 할 필요성을 느꼈다고 생각합니다. (IIRC 때문에 C ++ 11에서도 동일했습니다)
underscore_d

전에 C++03그것은이었다 C++98. 수많은 프로젝트에서 이식 가능한 C 대신 오래된 C ++를 사용했습니다. 때로는 이식성에 신경 써야합니다. 예를 들어 Solaris, AIX, HPUX, Windows에서 동일한 코드를 지원해야합니다. 컴파일러 의존성과 이식성에 관해서는 까다 롭습니다. 이식성 지옥을 소개하는 좋은 예는 reinterpret_cast코드에서 를 사용하는 것 입니다
Sasha Zezulinsky

다시 말하지만, 나와 같이 최신 버전의 언어로 훌륭하게 작동하는 플랫폼으로 만 자신을 제한하는 것이 기쁘다면 반대 의견이 제기됩니다.
underscore_d

1

먼저 int와 같은 특정 유형의 데이터가 있습니다.

int x = 0x7fffffff://==nan in binary representation

그런 다음 float과 같은 다른 유형과 동일한 변수에 액세스하려고합니다.

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

//this could only be used in cpp, looks like a function with template-parameters

또는

float y = *(float*)&(x);

//this could be used in c and cpp

요약 : 동일한 메모리가 다른 유형으로 사용됨을 의미합니다. 따라서 위와 같은 int 유형으로 float의 이진 표현을 float로 변환 할 수 있습니다. 예를 들어 0x80000000은 -0입니다 (가수와 지수는 null이지만 부호 msb는 1입니다). 이것은 또한 double과 long double에도 적용됩니다.

최적화 : reinterpret_cast는 많은 컴파일러에서 최적화 될 것이라고 생각하지만 c- 캐스팅은 포인터 산술로 수행됩니다 (값은 메모리에 복사되어야하며 포인터는 cpu 레지스터를 가리킬 수 없습니다).

참고 : 두 경우 모두 캐스트하기 전에 캐스트 된 값을 변수에 저장해야합니다! 이 매크로가 도움이 될 수 있습니다.

#define asvar(x) ({decltype(x) __tmp__ = (x); __tmp__; })

"동일한 메모리가 다른 유형으로 사용됨"을 의미하지만 특정 유형의 쌍으로 제한됩니다. 귀하의 예제 reinterpret_cast양식 int에서 float&정의되지 않은 동작입니다.
jaskmar

1

사용하는 한 가지 이유 reinterpret_cast는 기본 클래스에 vtable이 없지만 파생 클래스가있는 경우입니다. 이 경우, static_castreinterpret_cast(이 언급 비정형 될 경우 다른 포인터 값을 초래할 것이다 전술 jalf ). 면책 조항처럼, 이것이 표준의 일부가 아니라 여러 널리 퍼진 컴파일러의 구현이라고 진술하고 있습니다.

예를 들어 아래 코드를 사용하십시오.

#include <cstdio>

class A {
public:
    int i;
};

class B : public A {
public:
    virtual void func() {  }
};

int main()
{
    B b;
    const A* a = static_cast<A*>(&b);
    const A* ar = reinterpret_cast<A*>(&b);

    printf("&b = %p\n", &b);
    printf(" a = %p\n", a);
    printf("ar = %p\n", ar);
    printf("difference = %ld\n", (long int)(a - ar));

    return 0;
}

다음과 같은 결과가 나옵니다.

& b = 0x7ffe10e68b38
a = 0x7ffe10e68b40
ar = 0x7ffe10e68b38
차이 = 2

내가 시도한 모든 컴파일러 (MSVC 2015 및 2017, clang 8.0.0, gcc 9.2, icc 19.0.1- 마지막 3godbolt 참조 )에서 결과는 2 의 결과 static_cast와 다릅니다 reinterpret_cast(MSVC의 경우 4). 차이점에 대해 경고하는 유일한 컴파일러는 다음과 같이 clang이었습니다.

17:16 : 경고 : 'B *'클래스에서 '0이 아닌 오프셋에있는 기본으로'reinterpret_cast ''A * '는'static_cast '와 다르게 동작합니다. [-Wreinterpret-base-class]
const A * ar = reinterpret_cast (& b) ;
^ ~~~~~~~~~~~~~~~~~~~~~~~
17:16 : 참고 : 'static_cast'를 사용하여 업 캐스팅하는 동안 포인터를 올바르게 조정하십시오.
const A * ar = reinterpret_cast (& b) ;
^ ~~~~~~~~~~~~~~~
static_cast

마지막으로주의해야 할 점은 기본 클래스는 데이터 멤버가없는 경우 (예를 들어 있다는 것입니다 int i;) 다음 그 소리, GCC 및 ICC가 같은 주소를 반환 reinterpret_cast에 관해서는 static_castMSVC 여전히하지 않는 반면,.


1

다음은 reinterpret_castChris Luengo, flodin 및 cmdLP 가 언급 한 속성을 명확하게 보여주는 Avi Ginsburg 프로그램의 변형입니다 . 컴파일러가 지정된 메모리 위치를 마치 새로운 유형의 객체 인 것처럼 처리합니다.

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

class A
{
public:
    int i;
};

class B : public A
{
public:
    virtual void f() {}
};

int main()
{
    string s;
    B b;
    b.i = 0;
    A* as = static_cast<A*>(&b);
    A* ar = reinterpret_cast<A*>(&b);
    B* c = reinterpret_cast<B*>(ar);

    cout << "as->i = " << hex << setfill('0')  << as->i << "\n";
    cout << "ar->i = " << ar->i << "\n";
    cout << "b.i   = " << b.i << "\n";
    cout << "c->i  = " << c->i << "\n";
    cout << "\n";
    cout << "&(as->i) = " << &(as->i) << "\n";
    cout << "&(ar->i) = " << &(ar->i) << "\n";
    cout << "&(b.i) = " << &(b.i) << "\n";
    cout << "&(c->i) = " << &(c->i) << "\n";
    cout << "\n";
    cout << "&b = " << &b << "\n";
    cout << "as = " << as << "\n";
    cout << "ar = " << ar << "\n";
    cout << "c  = " << c  << "\n";

    cout << "Press ENTER to exit.\n";
    getline(cin,s);
}

다음과 같은 결과가 나옵니다.

as->i = 0
ar->i = 50ee64
b.i   = 0
c->i  = 0

&(as->i) = 00EFF978
&(ar->i) = 00EFF974
&(b.i) = 00EFF978
&(c->i) = 00EFF978

&b = 00EFF974
as = 00EFF978
ar = 00EFF974
c  = 00EFF974
Press ENTER to exit.

B 객체가 메모리에 B 특정 데이터로 내장 된 다음 내장 된 A 객체가 뒤 따르는 것을 볼 수 있습니다. 는 static_cast정확하게 삽입 된 객체의 주소를 반환하고,에 의해 생성 된 포인터 static_cast올바르게 데이터 필드의 값을 제공한다. reinterpret_cast취급에 의해 생성 된 포인터b 는 일반 A 객체 인 것처럼 메모리의 메모리 위치를 하므로 포인터가 데이터 필드를 가져 오려고하면이 필드의 내용 인 것처럼 일부 B 관련 데이터를 반환합니다.

reinterpret_cast포인터와 부호없는 정수의 크기가 같은 경우 포인터를 부호없는 정수로 변환하는 것이 한 가지 용도입니다 .

int i; unsigned int u = reinterpret_cast<unsigned int>(&i);


-6

빠른 답변 : static_cast컴파일하면 사용 하고 그렇지 않으면를 사용 하십시오 reinterpret_cast.


-16

FAQ를 읽으십시오 ! C에서 C ++ 데이터를 보유하는 것은 위험 할 수 있습니다.

C ++에서 void *캐스트없이 객체에 대한 포인터를 변환 할 수 있습니다 . 그러나 다른 방법으로는 사실이 아닙니다. 당신은 필요한 것 static_cast원래의 포인터 등을 얻을 수 있습니다.

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