5

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
  • 75
  • 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

3 Answers3

7

"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
πάντα ῥεῖ
  • 85,314
  • 13
  • 111
  • 183
  • 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
  • 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
  • 369,052
  • 73
  • 620
  • 1,021
1

You could inspect each character of the address value by looking at its ASCII value (with the ord() function or something like that) and only modify the ASCII values within a certain range (the character range, starting somewhere around 93 with 'a') by transforming the value into the ASCII value of the corresponding upper case character and transform them back (with the char() function).

I'm aware that this is a very hacky approach.

Edit: this will also transform the second 'x' into 'X'

Luciano van der Veekens
  • 5,937
  • 4
  • 23
  • 30