Skip to content

29 Beginner The Hundred

The Format That Would Not Leave

one value asked for hex; two of them got it

#include <iomanip>
#include <iostream>

int main() {
    int mask = 255;
    int slots = 16;

    std::cout << "mask:  " << std::hex << mask << '\n';   // a bit mask reads better in hex
    std::cout << "slots: " << slots << '\n';

    std::cout << std::setw(8) << "left" << "right" << '\n';
}

Run it. What does it print?

Answer
mask:  ff
slots: 10
    leftright

slots is still 16 — printed in hex, one statement later. And only left got the width.

Why

Almost every manipulator is a setter: std::hex flips the stream's basefield flag and leaves it flipped, so every integer printed afterwards — later in the statement, later in the program, inside any function that touches std::cout — comes out in base 16. That is why slots prints 10. std::setw is the one exception: it sets std::cout.width(), and every formatted output operation resets the width to 0 as soon as it has consumed it, so "left" is padded to eight columns and "right" is not. The split is worth memorizing — setfill, setprecision, boolalpha and showbase all stick; only width is single-use. Nothing here is malformed code, so -Wall -Wextra says nothing.

The fix

Save the flags and put them back, so callers get the stream they lent you:

std::ios::fmtflags saved = std::cout.flags();
std::cout << "mask:  " << std::hex << mask << '\n';
std::cout.flags(saved);                     // restored
std::cout << "slots: " << slots << '\n';    // prints 16

A plain std::cout << std::dec works too, and std::setw simply has to be repeated for every column you want padded. Since C++20 there is a cleaner escape: std::format takes its formatting per call and never touches stream state — though libstdc++ only ships <format> from GCC 13, so g++ 11 rejects the include.

Takeaway: formatting is stream state, not a per-argument option — except setw, which is spent on the very next item.

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

Open in Compiler Explorer ↗ Quiz this entry