drbombe
drbombe

Reputation: 639

Why there is no output from `cout` but it is ok for `printf`

To clear illustrate the problem, here is a minimal code. Why there is no output for my line cout << z << endl;? I am running it on Mac OS, compiler is Apple clang version 12.0.0 (clang-1200.0.32.29) Target: x86_64-apple-darwin20.3.0

#include <iostream>

using namespace std;
int main() {
  int x = 15;
  int *y = &x;
  unsigned char *z = (unsigned char *)&x;
  cout << y << endl; //this line works OK
  cout << z << endl; //no output of this line
  printf("%x", z); // this line works OK
  return 0;
}

Upvotes: 0

Views: 417

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596287

operator<< does not have an overload for an int* pointer, so the expression cout << y ends up calling the void* overload, which prints the memory address that the pointer is pointing at. It doesn't try to access the data being pointed at. Same with printf("%x", z).

operator<< does have an overload for an unsigned char* pointer, which treats the pointer as pointing to a null-terminated string, same as the char* overload does. But z is not a pointer to a null-terminated string, so your code has undefined behavior when trying to print z this way. To print the address that z is pointing at, you need an explicit typecast to void*, eg:

cout << static_cast<void*>(z)

That being said, the reason your code doesn't just fail outright is because the numeric value 15 (hex 0x0F) as an int happens to contain several 0x00 bytes in it (3 of them, if int is 4 bytes in size, as it is on most platforms). Depending on endian, the int will be laid out in memory as either 0F 00 00 00 or 00 00 00 0F. So, trying to print z as a null-terminated string will encounter one of those 0x00 bytes and interpret it as a null terminator. If the 0x0F byte is encountered first, it will simply be interpreted as an ASCII control character that has no visual representation. Either way, you won't see anything being printed to the console.

Upvotes: 3

Related Questions