Proper way of casting pointer types

前端 未结 3 1957
忘掉有多难
忘掉有多难 2020-12-08 02:06

Considering the following code (and the fact that VirtualAlloc() returns a void*):

BYTE* pbNext = reinterpret_cast(
    VirtualAlloc(NULL, cbAll         


        
3条回答
  •  臣服心动
    2020-12-08 03:12

    You should static_cast. Use static_cast in cases where you're undoing an implicit conversion.

    In this particular case, however, there is no difference because you're converting from void*. But in general, reinterpret_casting between two object pointers is defined to be (§5.2.10/7):

    An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

    Emphasis mine. Since T1 for you is already void*, the cast to void* in reinterpret_cast does nothing. This is not true in general, which is what Drew Dormann is saying:

    #include 
    
    template 
    void print_pointer(const volatile T* ptr)
    {
        // this is needed by oversight in the standard
        std::cout << static_cast(const_cast(ptr)) << std::endl;
    }
    
    struct base_a {};
    struct base_b {};
    struct derived : base_a, base_b {};
    
    int main()
    {
        derived d;
    
        base_b* b = &d; // implicit cast
    
        // undo implicit cast with static_cast
        derived* x = static_cast(b);
    
        // reinterpret the value with reinterpret_cast
        derived* y = reinterpret_cast(b);
    
        print_pointer(&d);
        print_pointer(x);
        print_pointer(y);
    }
    

    Output:

    00CBFD5B
    00CBFD5B
    00CBFD5C

    (Note that because y doesn't actually point to a derived, using it is undefined behavior.)

    Here, reinterpret_cast comes up with a different value because it goes through void*. This is why you should use static_cast when you can, and reinterpret_cast when you have to.

提交回复
热议问题