c++pointersiostreamvolatilestandards-compliance

Why does std::cout convert volatile pointers to bool?


If you try to cout a pointer to a volatile type, even a volatile char pointer where you would normally expect cout to print the string, you will instead simply get '1' (assuming the pointer is not null I think). I assume output stream operator<< is template specialized for volatile pointers, but my question is, why? What use case motivates this behavior?

Example code:

#include <iostream>
#include <cstring>

int main()
{
    char x[500];
    std::strcpy(x, "Hello world");

    int y;
    int *z = &y;

    std::cout << x << std::endl;
    std::cout << (char volatile*)x << std::endl;

    std::cout << z << std::endl;
    std::cout << (int volatile*)z << std::endl;

    return 0;
}

Output:

Hello world
1
0x8046b6c
1

Solution

  • Up through the C++20 standard, ostream::operator<< has the following overloads, among others:

    ostream& operator<< (bool val );
    ostream& operator<< (const void* val );
    

    When you pass in a volatile pointer, the second overload can't apply because volatile pointers cannot be converted to non-volatile without an explicit cast. However, any pointer can be converted to bool, so the first overload is chosen, and the result you see is 1 or 0.

    So the real reason for this is not an intentional decision on behalf of the standards committee, but simply that the standard does not specify an overload that takes a volatile pointer.


    2023 Update

    Beginning with the C++23 standard (draft N4944, cppreference), ostream::operator<< adds the following overload:

    basic_ostream& operator<<( const volatile void* value );
    

    When compiling in C++23 mode (if your compiler supports it), volatile pointers are now formatted as you'd expect, instead of being implicitly converted to bool.