Kiyya
Kiyya

Reputation: 19

What is the difference between the conversion (obj1*)(void*)p and (obj1*)p where p is a pointer to obj2 type

Background: I encountered this in GCC c++ standard library extension pool_allocator.h, which contains an allocator type that utilize memory pool to improve the efficiency of small chunk memory allocation. In the member function _M_refill() of __pool_alloc_base it need to deal with the type conversion from char* (which is used for raw memory management) to _Obj* (which is the list node struct used to manage the free chunk).

The situation is simpilified as following: I have a pointer p to obj2 type, and I need to convert it to obj1 type, where obj1 and obj2 have totally no inheritance relationship. There are two ways to achieve this:

My question is: What is the differences between these two? Why would GCC choose the second way? (I think the first one will just work fine as the second one)

What I have tried: I have asked DeepSeekR1 about this, and he thinks there is no difference(all same as reinterpret_cast<obj1*>(p)). I guess this might be related to some platform/compiler-specific problems and is out of safety concerns.

Complement:

Here is the member function _M_refill who receive a parameter which is the block size of the free list that need to be refilled. This function is called when the free list of a certain size block is empty. It first use _M_allocate_chunk to allocate a big chunk of raw memory(as you see the return type is char*) and then build the free list structure upon the raw memory using the __Obj.

void* __pool_alloc_base::_M_refill(size_t __n) {
    int __nobjs = 20;
    char* __chunk = _M_allocate_chunk(__n, __nobjs);
    _Obj* volatile* __free_list;
    _Obj* __result;
    _Obj* __current_obj;
    _Obj* __next_obj;

    if (__nobjs == 1)
      return __chunk;
    __free_list = _M_get_free_list(__n);

    // Build free list in chunk.
    __result = (_Obj*)(void*)__chunk;
    *__free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
    for (int __i = 1; ; __i++) {
        __current_obj = __next_obj;
        __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
        if (__nobjs - 1 == __i) {
            __current_obj->_M_free_list_link = 0;
            break;
        }
        else
            __current_obj->_M_free_list_link = __next_obj;
    }
    return __result;
  }

Definition of __Obj

union _Obj {
    union _Obj* _M_free_list_link;
    char        _M_client_data[1];
};

English is not my native language, so the description might be unclear somewhere, please pointing out wherever unclear and I will try my best to clarify them.

Upvotes: 1

Views: 112

Answers (0)

Related Questions