As a part of hashing, I need to convert a function pointer to a string representation. With global/static functions it's trivial:
string s1{ to_string(reinterpret_cast<uintptr_t>(&global)) };
And from here:
2) Any pointer can be converted to any integral type large enough to hold the value of the pointer (e.g. to
std::uintptr_t
)
But I have a problems with member functions:
cout << &MyStruct::member;
outputs 1
though in debugger I can see the address.
string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) };
Gives a compile-time error cannot convert
. So it seems that not any pointer can be converted.
What else can I do to get a string representation?
cout << &MyStruct::member;
outputs
1
though in debugger I can see the address.
There is no overload for ostream::operator<<(decltype(&MyStruct::member))
. However, the member function pointer is implicitly convertible to bool
and for that, there exists an overload and that is the best match for overload resolution. The converted value is true
if the pointer is not null. true
is output as 1
.
string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) };
Gives a compile-time error cannot convert. So it seems that not any pointer can be converted.
Perhaps confusingly, in standardese pointer is not an umbrella term for object pointers, pointers-to-members, pointers-to-functions and pointers-to-member-functions. Pointers mean just data pointers specifically.
So, the quoted rule does not apply to pointers-to-member-functions. It only applies to (object) pointers.
What else can I do to get a string representation?
You can use a buffer of unsigned char
, big enough to represent the pointer, and use std::memcpy
. Then print it in the format of your own choice. I recommend hexadecimal.
As Martin Bonner points out, the pointer-to-member may contain padding in which case two values that point to the same member may actually have a different value in the buffer. Therefore the printed value is not of much use because two values are not comparable without knowing which bits (if any) are padding - which is implementation defined.
Unfortunately I need a robust solution so because of this padding I can't use.
No portable robust solution exists.
As Jonathan Wakely points out, there is no padding in the Itanium ABI, so if your compiler uses that, then the suggested memcpy method would work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With