Why doesn't this reinterpret_cast compile?

前端 未结 11 655
暗喜
暗喜 2020-12-04 16:32

I understand that reinterpret_cast is dangerous, I\'m just doing this to test it. I have the following code:

int x = 0;
double y = reinterpret_c         


        
相关标签:
11条回答
  • 2020-12-04 16:43

    reinterpret_cast is best used for pointers. So a pointer to one object can be turned into a "submarine".

    From msdn:

    The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.

    The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.

    0 讨论(0)
  • 2020-12-04 16:43

    Casting an int to a double doesn't require a cast. The compiler will perform the assignment implicitly.

    The reinterpret_cast is used with pointers and references, e.g., casting an int * to a double *.

    0 讨论(0)
  • 2020-12-04 16:44

    The reinterpret approach led me down a strange path with inconsistent results. In the end I found it much better to memcpy like this!

    double source = 0.0;
    uint64_t dest;
    memcpy(&dest, &source, sizeof(dest));
    
    0 讨论(0)
  • 2020-12-04 16:46

    Reinterpret cast allows you to reinterpret a block of memory as a different type. This has to be performed on pointers or references:

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

    The other thing is that it is in fact a quite dangerous cast, not only due to strange values coming out as results, or the assert above not failing, but because if the types are of different sizes, and you reinterpret from 'source' to 'destination' types, any operation on the reinterpreted reference/pointer will access sizeof(destination) bytes. If sizeof(destination)>sizeof(source) then that will step beyond the actual variable memory, potentially killing your application or overwritting other variables other than the source or destination:

    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.
    assert( t.y != 20 );
    
    0 讨论(0)
  • 2020-12-04 16:48

    The compiler rejects what you wrote as nonsense because int and double may be objects with different sizes. You could achieve the same effect this way, although it is certainly dangerous:

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

    This is potentially dangerous because if x and y are diffrent sizes (let's say int is four bytes and double is eight bytes) then when you dereference the eight bytes of memory at &x to fill in y you will access four bytes of x and four bytes of ... whatever comes next in memory (possibly the start of y, or garbage, or something else entirely.)

    If you want to convert a integer to a double, use a static_cast and it will perform conversion.

    If you want to access the bit-pattern of x, cast to some convenient pointer type (say, byte*) and access up to sizeof(int) / sizeof(byte):

    byte* p = reinterpret_cast<byte*>(&x);
    for (size_t i = 0; i < sizeof(int); i++) {
      // do something with p[i]
    }
    
    0 讨论(0)
  • 2020-12-04 16:49

    That's interesting. Maybe it's doing an implicit conversion from int to float before it attempts the cast to double. int and float types tend to be the same size in bytes (depending on your system of course).

    0 讨论(0)
提交回复
热议问题