Jay Jay - 1 year ago 30
C++ Question

C++ printing pointer doesn't acknowledge showbase

I've noticed a discrepancy in the way we print pointers. gcc by default is adding 0x prefix to hex output of pointer, and Microsoft's compiler doesn't do that. showbase/noshowbase doesn't affect either of them.

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
void * n = (void *)1;
cout << noshowbase << hex << n << dec << endl;
// output (g++ (GCC) 4.7.2, 5.4.0): 0x1
// output (VS 2010, 2013): 00000001

n = (void *)10;
cout << noshowbase << hex << n << dec << endl;
// output (g++ (GCC) 4.7.2, 5.4.0): 0xa
// output (VS 2010, 2013): 0000000A

n = (void *)0;
cout << noshowbase << hex << n << dec << endl;
// output (g++ (GCC) 4.7.2, 5.4.0): 0
// output (VS 2010, 2013): 00000000

return 0;
}


I assume this is implementation defined behavior and not a bug, but is there a way to stop any compiler from prepending the 0x? We are already prepending the 0x on our own but in gcc it comes out like 0x0xABCD.

I'm sure I could do something like
ifdef __GNUC___ ....
but I wonder if I'm missing something more obvious. Thanks

Answer Source

I propose that you cast to intptr and treat the input as a normal integer.
Your I/O manipulators should then work.

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    void * n = (void *)1;
    cout << noshowbase << hex << reinterpret_cast<intptr_t>(n) << dec << endl;

    n = (void *)10;
    cout << noshowbase << hex << reinterpret_cast<intptr_t>(n) << dec << endl;

    n = (void *)0;
    cout << noshowbase << hex << reinterpret_cast<intptr_t>(n) << dec << endl;
}

// 1
// a
// 0

(live demo)

At first I was a little surprised by your question (more specifically, by these implementations' behaviour), but the more I think about it the more it makes sense. Pointers are not numbers*, and there's really no better authority on how to render them than the implementation.

* I'm serious! Although, funnily enough, for implementation/historical reasons, the standard calls a const void* "numeric" in this context, using the num_put locale stuff for formatted output, ultimately deferring to printf in [facet.num.put.virtuals]. The standard states that the formatting specifier %p should be used but, since the result of %p is implementation-defined, you could really get just about anything with your current code.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download