8

I'm trying to print the address(reference) of a variable in hex and that too in upper case. But I see that I'm able to print the hex equivalent of 77 in upper case, but not the address(reference) of a variable. Can somebody help me please?

The following is the program I have the difficulty with.

#include <iostream>
#include <string>

using namespace std;


void print_nb_of_items(const int nb_of_apple, const int& nb_of_pens)
{
    cout << "Number of apples = " << nb_of_apple << endl;
    cout << "Number of pens = " << nb_of_pens << " Address = " << uppercase << hex << &nb_of_pens << endl;
    cout << "Hex output in uppercase = " << uppercase << hex << 77 << endl;
}

/* The main function */

int main(int argc, char * argv[])
{
    int nb_apple = 24;
    int nb_pens = 65;
    print_nb_of_items(nb_apple, nb_pens);

    return 0;
}

The output for the program I got is:

Number of apples = 24
Number of pens = 65 Address = 0xbffbd438
Hex output in uppercase = 4D

I want the address to be printed as: 0xBFFBD438. How do I do that?

Venkata Pavan
  • 105
  • 1
  • 1
  • 4
  • Works fine for me. What compiler do you use? – Christian Hackl Mar 01 '15 at 15:17
  • 3
    cast to `uintptr_t`? Output of pointers is hex only "by convention", not defined by the standard. If you have a C++ compiler for, say, PDP-11, it may well output addresses in octal, as that is the general standard output format for pointers in that architecture. – Mats Petersson Mar 01 '15 at 15:17
  • @ChristianHackl Doesn't for me here: http://ideone.com/K1Dwy1 – πάντα ῥεῖ Mar 01 '15 at 15:18
  • @πάνταῥεῖ: Well, I've never really gotten into all the stream manipulators. A quick workaround could be to read the value into a stringstream and convert the resulting string to uppercase (always keeping in mind that the hex representation itself is platform-specific). – Christian Hackl Mar 01 '15 at 15:23
  • @ChristianHackl As Mats mentioned implementation of output for `void*` is not clearly defined. – πάντα ῥεῖ Mar 01 '15 at 15:25
  • 1
    What is this "address (reference)" terminology you've employed? References and pointers are different things. – Lightness Races in Orbit Mar 01 '15 at 15:57

2 Answers2

8

"I want the address to be printed as: 0xBFFBD438. How do I do that?"

Well, @MatsPetterson hit the nail on the head in his comment, casting the address value to a uintptr_t

cout << "Number of pens = " << nb_of_pens 
     << " Address = 0x" << uppercase << hex 
     << uintptr_t(&nb_of_pens) << endl;
     // ^^^^^^^^^^           ^

just makes it work fine (see fully working sample here please).


To explain in more depth:
The implementation of

 std::ostream operator<<(ostream& os, void* ptr);

isn't further specified by the standard, and may simply not be affected by/considering the std::uppercase I/O manipulator. Conversion of the pointer value to a plain number, will take the std::uppercase and std::hex I/O manipulators into effect.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 2
    Why not `reinterpret_cast`? – Christian Hackl Mar 01 '15 at 15:26
  • I once had [this silly discussion](http://stackoverflow.com/questions/19562103/uint8-t-cant-be-printed-with-cout/19562163#19562163) already. I prefer shortness for formatting purposes. – πάντα ῥεῖ Mar 01 '15 at 15:31
  • 1
    Not to mention that C-style casts don't get incorrectly written as reinterpret_cats ... :) – Mats Petersson Mar 01 '15 at 15:43
  • @MatsPetersson: Isn't `reinterpret_cast` the only of the C++-style casts which works here? – Christian Hackl Mar 01 '15 at 15:49
  • @ChristianHackl Yes. But well, as mentioned for readability and purpose it looks just overkill for me. – πάντα ῥεῖ Mar 01 '15 at 15:53
  • @πάνταῥεῖ: I realise that. I was just wondering, after reading Mats' comment, if there was more to this than readability. – Christian Hackl Mar 01 '15 at 15:54
  • 1
    None of the other C++ style casts will work, but compiler will do the right thing with a C-style cast (the problem with C-style casts is generally that they WILL do `reinterpret_cast` when that's not quite what you wanted - and of course, the ability to search for `_cast` is much better than to try to search for `(random_type)`) – Mats Petersson Mar 01 '15 at 15:54
2

Like printf("%p", &obj), the stream output format of a pointer is entirely unspecified. By convention we get a hexadecimal value and, on some systems, that abides by std::uppercase (and friends). But you cannot rely on that. Those I/O manipulators are there for numbers, not pointers.

You can actually transform your pointer into a number to guarantee the behaviour you want:

cout << "Number of pens = " << nb_of_pens
     << " Address = " << uppercase << hex << uintptr_t(&nb_of_pens)
     << endl;
Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055