Search code examples
c++printfstandards-compliancepointer-to-member

Printing a pointer-to-member-field


I was debugging some code involving pointers to member fields, and i decided to print them out to see their values. I had a function returning a pointer to member:

#include <stdio.h>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
    switch (what) {
    case 0: return &test::x;
    case 1: return &test::y;
    case 2: return &test::z;
    default: return NULL;
    }
}

I tried using cout:

#include <iostream>
int main()
{
    std::cout << select(0) << " and " << select(3) << '\n';
}

I got 1 and 0. I thought the numbers indicated the position of the field inside the struct (that is, 1 is y and 0 is x), but no, the printed value is actually 1 for non-null pointer and 0 for null pointer. I guess this is a standard-compliant behavior (even though it's not helpful) - am i right? In addition, is it possible for a compliant c++ implementation to print always 0 for pointers-to-members? Or even an empty string?

And, finally, how can i print a pointer-to-member in a meaningful manner? I came up with two ugly ways:

printf("%d and %d\n", select(0), select(3)); // not 64-bit-compatible, i guess?

ptr_to_member temp1 = select(0); // have to declare temporary variables
ptr_to_member temp2 = select(3);
std::cout << *(int*)&temp1 << " and " << *(int*)&temp2 << '\n'; // UGLY!

Any better ways?


Solution

  • Member pointers aren't ordinary pointers. The overloads you expect for << aren't in fact there.

    If you don't mind some type punning, you can hack something up to print the actual values:

    int main()
    {
      ptr_to_member a = select(0), b = select(1);
      std::cout << *reinterpret_cast<uint32_t*>(&a) << " and "
                << *reinterpret_cast<uint32_t*>(&b) << " and "
                << sizeof(ptr_to_member) << '\n';
    }