Skip to content

C.183: The Stream Insertion Operator << Is Not Defined for std::byte #2271

Open
@ckwastra

Description

@ckwastra

Reference:

Example, bad

union Pun {
    int x;
    unsigned char c[sizeof(int)];
};

The idea of Pun is to be able to look at the character representation of an int.

void bad(Pun& u)
{
    u.x = 'x';
    cout << u.c[0] << '\n';     // undefined behavior
}

If you wanted to see the bytes of an int, use a (named) cast:

void if_you_must_pun(int& x)
{
    auto p = reinterpret_cast<std::byte*>(&x);
    cout << p[0] << '\n';     // OK; better
    // ...
}

Accessing the result of a reinterpret_cast from the object's declared type to char*, unsigned char*, or std::byte* is defined behavior. (Using reinterpret_cast is discouraged, but at least we can see that something tricky is going on.)

The expression cout << p[0] does not compile because there is no operator<< overload that accepts a std::byte. This makes sense—std::byte represents raw binary data, not a printable character. To print its value, we can convert it to a suitable type using std::to_integer:

void if_you_must_pun(int& x)
{
    auto p = reinterpret_cast<std::byte*>(&x);
-   cout << p[0] << '\n';     // OK; better
+   cout << std::to_integer<char>(p[0]) << '\n';     // OK; better
    // ...
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions