Reputation: 1127
Pointers to functions are not plain data pointers as they cannot be stored in a void* pointer. Nonetheless, it seems that I can store the copy of a function-pointer in dynamic memory (in gcc and clang) like in the code below. Is such a code legal according to the C++ Standard, or maybe this is some sort of compiler extension?
Moreover, the resulting pointer to function-pointer behaves as a plain data pointer: I can store it in void* and retrieve it from void* by static_cast. Is this behavior guranteed by the Standard?
int main()
{
extern void fcn();
void (*fcnPtr)() = &fcn;
void (**ptrToFcnPtr)() = nullptr;
//Make the copy of fcnPtr on the heap:
ptrToFcnPtr = new decltype(fcnPtr)(fcnPtr);
//Call the pointed-to function :
(**ptrToFcnPtr)();
//Save the pointer in void* :
void *ptr = ptrToFcnPtr;
//retrieve the original ptr:
auto myPtr = static_cast< void(**)() > (ptr) ;
//free memory:
delete ptrToFcnPtr ;
}
Upvotes: 33
Views: 1507
Reputation: 15951
While function pointers are not object pointers, "pointer to function of some type" is still an object type [basic.types]/8. Thus, function pointers are themselves objects, just the thing they point to is not.
Thus, you sure can create an object of function pointer type via a new expression…
Upvotes: 27
Reputation: 238411
as they (function pointers) cannot be stored in a void* pointer.
Actually, storing a function pointer as a void*
is conditionally supported. This means that either it can or cannot be stored depending on the language implementation. If the language implementation supports dynamic loading, then converting function pointer in void*
probably is supported. GCC, Clang and MSVC all support this:
reinterpret_cast<void*>(&function);
Is it legal to new-allocate a pointer to function?
Sure. All pointers, including function pointers, are objects and all objects can be allocated dynamically.
Moreover, the resulting pointer to function-pointer behaves as a plain data pointer
Function pointer is an object. Pointer to a function pointer not only "behaves as", but is a pointer to an object.
I can store it in void* and retrieve it from void* by static_cast. Is this behavior guranteed by the Standard?
Conversion between pointer to void and pointer to object is allowed, yes. And round-trip conversion is guaranteed to yield the original pointer.
Upvotes: 9