First, there is no requirement that std::cout
(or even std::cerr
) be
unbuffered. The only requirement is that std::cerr
have
std::basic_ios::unitbuf
set (so that it will flush at the end of each
output function: <<
or a non-formatted output function). On the other
hand, unless you've called std::basic_ios::sync_with_stdio(false)
,
outputting to the C++ streams and outputting to the corresponding
C streams (i.e. std::cout
and stdout
) must have the same effects.
In theory, this can be done in several ways: stdout
functions can
forward to those of std::cout
, std::cout
output can forward to
stdout
, or they can share some common buffer implementation under the
hood. In practice, practically all implementations have std::cout
forwarding to stdout
.
C specifies that stderr
not be fully buffered, and that stdout
may
be fully buffered only if it can be determined not to refer to an
interactive device (for some implementation defined meaning of
"interactive device"). Typically, stdout
will be line buffered (a
concept which doesn't exist in iostream), and stderr
will be
unbuffered, but that's not guaranteed by the C standard (and may not be
true today—the last time I really looked was over twenty years
ago). Anyway, an implementation which just forwards to stdout
will
follow the rules of the C implementation it forwards to, and one that
doesnt' still needs to take some steps to ensure that output to
std::cout
and stdout
comes out in the right order, and that stdout
behaves "as if" it obeyed the C rules.
If you're worried about performance, then you might want to run some
trials. Try measuring the time it takes to output to an std::ofstream
you've opened yourself, versus the time it takes to output to
std::cout
(both with and without having called sync_with_stdio
),
with the output redirected. The differences should be interesting.