Reputation: 14603
I want to do something like this in a well-defined manner:
struct S
{
static some_integral_type f() noexcept
{
return some_cast<...>(&f);
}
};
The integer can be signed or unsigned. The result should be the same as the casts of object pointers to uintptr_t
or intptr_t
produce. AFAIK casts to those are not guaranteed to be possible for function pointers. Even casts to uintmax_t
and intmax_t
might not work for all I know.
I need this so I can produce a unique "handle" from a function pointer, that I can then use in a switch
statement.
Upvotes: 2
Views: 241
Reputation: 45704
In general, no.
First, member-function-pointers (and member-pointers) are hairy beasts the standard says very little about.
So, let's ignore them for now.
Next, it might not even be possible to round-trip plain old function-pointers through void*
, and the standard only defines a type for round-tripping data-pointers through integers, if the implementation supports such:
(u)intptr_t
.
Naturally, if your implementation has a large enough integer-type, you can manually do it by reading the pointer as an unsigned char[]
and combining it to a single numeric value, the operation then being reversible.
Be aware that equal function-pointers can result in different numbers if you go that route though, as the same pointer can have multiple possible representations (for example padding bytes, non-value-bits, segmentation)...
Upvotes: 4
Reputation: 147036
You can attempt to select an integer of the same size as the function pointer with a metafunction- the required size being sizeof(void(*)())
. However, there's no guarantee that any such integer type exists.
Realistically speaking, casting it to void* or intptr_t is gonna work on pretty much all the mainstream platforms.
Upvotes: 1
Reputation: 26483
Taken from Can std::hash be used to hash function pointers?
In a previous attempt I attempted to cast the function pointer to void*, which isn't allowed and doesn't compile (see: https://isocpp.org/wiki/faq/pointers-to-members#cant-cvt-memfnptr-to-voidptr for details). The reason is that a void* is a data pointer, while a function pointer is a code pointer.
Upvotes: 0