Reinterpret_cast vs. C-style cast

前端 未结 6 1600
谎友^
谎友^ 2020-12-01 03:06

I hear that reinterpret_cast is implementation defined, but I don\'t know what this really means. Can you provide an example of how it can go wrong, and it goes

6条回答
  •  悲&欢浪女
    2020-12-01 03:36

    It is implementation defined in a sense that standard doesn't (almost) prescribe how different types values should look like on a bit level, how address space should be structured and so on. So it's really a very platform specific for conversions like:

    double d;
    int &i = reinterpret_cast(d);
    

    However as standard says

    It is intended to be unsurprising to those who know the addressing structure of the underlying machine.

    So if you know what you do and how it all looks like on a low-level nothing can go wrong.

    The C-style cast is somewhat similar in a sense that it can perform reinterpret_cast, but it also "tries" static_cast first and it can cast away cv qualification (while static_cast and reinterpret_cast can't) and perform conversions disregarding access control (see 5.4/4 in C++11 standard). E.g.:

    #include 
    
    using namespace std;
    
    class A { int x; };
    class B { int y; };
    
    class C : A, B { int z; };
    
    int main()
    {
      C c;
    
      // just type pun the pointer to c, pointer value will remain the same
      // only it's type is different.
      B *b1 = reinterpret_cast(&c);
    
      // perform the conversion with a semantic of static_cast(&c), disregarding
      // that B is an unaccessible base of C, resulting pointer will point
      // to the B sub-object in c.
      B *b2 = (B*)(&c);
    
      cout << "reinterpret_cast:\t" << b1 << "\n";
      cout << "C-style cast:\t\t" << b2 << "\n";
      cout << "no cast:\t\t" << &c << "\n";
    }
    

    and here is an output from ideone:

    reinterpret_cast:  0xbfd84e78
    C-style cast:      0xbfd84e7c
    no cast:           0xbfd84e78
    

    note that value produced by reinterpret_cast is exactly the same as an address of 'c', while C-style cast resulted in a correctly offset pointer.

提交回复
热议问题