Reputation: 19
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:
(obj1*)p
(obj1*)(void*)p
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