Sunday 2 April 2017

c++ - How to print function pointers with cout?

Regarding your specific question,





how can we observe the content of a
member function pointers?




The answer is, other than converting them to bool to express that it points to something or it doesn't, you can't 'observer' member function pointers. At least not in a compliant way. The reason is because the standard explicitly disallows this:



4.12 footnote 57:





57) The rule for conversion of
pointers to members (from pointer to
member of base to pointer to member of
derived) appears inverted compared to
the rule for pointers to objects (from
pointer to derived to pointer to base)
(4.10, clause 10). This inversion is
necessary to ensure type safety. Note
that a pointer to member is not a
pointer to object or a pointer to

function and the rules for conversions
of such pointers do not apply to
pointers to members. In particular, a
pointer to member cannot be converted
to a void*.




For example, here is sample code:



#include 

#include
#include
#include
#include
using namespace std;

class Gizmo
{
public:
void DoTheThing()

{
return;
};


private:
int foo_;
};

int main()

{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;

Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way

bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
return 0;

}


I note that my debugger (MSVC9) is able to tell me the actual physical address of the member function at runtime, so I know there must be some way to actually get that address. But I'm sure it is non-conformant, non-portable and probably involves machine code. If I were to go down that road, I would start by taking the address of the function pointer (eg &fn), casting that to void*, and go from there. This would also require you know the size of pointers (different on different platforms).



But I would ask, so long as you can convert the member-function pointer to bool and evaluate the existance of the pointer, why in real code would you need the address?



Presumably the answer to the last question is "so I can determine if one function pointer points to the same function as another." Fair enough. You can compare function pointers for equality:



#include 

#include
#include
#include
#include
using namespace std;

class Gizmo
{
public:
void DoTheThing()

{
return;
};

**void DoTheOtherThing()
{
return;
};**



private:
int foo_;
};

int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;

Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way


bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;

**void(Gizmo::*fnOther)(void) = &Gizmo::DoTheOtherThing;

bool same = fnOther == fn;
bool sameIsSame = fn == fn;**


return 0;
}

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...