Skip to content

12 Beginner The Hundred

The Pointer That Printed Its Contents

the same pointer, printed twice, two different answers

#include <iostream>

int main() {
    int count = 7;
    const char* label = "widgets";

    std::cout << "count is at " << &count << '\n';
    std::cout << "label is at " << label << '\n';
    std::cout << "label is at " << static_cast<const void*>(label) << '\n';
}

Run it. Which of the three lines print an address?

Answer

Two of them. Typical output (GCC on x86-64; your addresses will differ, and the stack one changes from run to run):

count is at 0x7fff308da584
label is at widgets
label is at 0x402010

Same pointer on the last two lines; only the cast got an address out of it.

Why

operator<< handles pointers with a catch-all const void* overload — any object pointer converts to it, which is how &count becomes an address. Character pointers never reach it: std::ostream also has dedicated overloads for const char* (plus the signed and unsigned char flavours) that treat the pointer as a NUL-terminated string, and an exact match beats a conversion every time. So label prints its contents, and the only way to see where it points is to launder it through a cast. The flip side is nastier — stream a char* whose bytes are not NUL-terminated and the stream reads straight off the end, undefined behavior that often looks like it worked, because some zero byte usually turns up soon after. Only narrow character pointers get the text treatment — a char16_t literal prints as an address under C++17, and C++20 deletes that overload so the line stops compiling at all.

-Wall -Wextra says nothing about any of this — the compiler assumes you meant it.

The fix

Cast when you want the pointer value rather than the text:

std::cout << static_cast<const void*>(label) << '\n';   // 0x402010 — the address
std::cout << label << '\n';                             // widgets  — the contents

Takeaway: to iostreams a char* is text, never a pointer value — say static_cast<const void*> when you want the address.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry