Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get string representation for the member function?

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?

like image 442
nikitablack Avatar asked Apr 25 '16 08:04

nikitablack


1 Answers

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.

like image 71
eerorika Avatar answered Oct 27 '22 15:10

eerorika