[COFF] C with Improvements :-)

Dan Cross crossd at gmail.com
Tue Jun 24 22:07:16 AEST 2025


On Mon, Jun 23, 2025 at 9:36 AM Douglas McIlroy
<douglas.mcilroy at dartmouth.edu> wrote:
> > Overloading bit shifting operators to implement stream I/O was a repellent choice
>
> Without commenting on this judgement, I can tell how the convention
> came about in a casual conversation.

Thank you for this interesting historical note, Doug.

Personally, I've never found the `<<` or `>>` syntax troubling when
using C++ IO streams, and the type safety is a notable improvement
over printf/scanf et al.

What I _do_ find troubling is that the stream itself is a stateful,
mutable object, so to perform any sort of non-trivial formatting, one
has to inject special control messages into the stream using the same
syntax; these do compose (usually), but they're persistent, are overly
verbose, and cumbersome to use in practice. Here, the concision of
printf's "little language" of formatting verbs is superior, and far
more readable.

It seems obvious in retrospect that C++ would have been better off if
augmented with a small hierarchy of "formatting objects" that encoded
the various formatting directives, exposing a printf-like language, as
a constructor argument, along with the datum. The stream would consume
these for the purposes of formatting that specific datum, but then
discard them, as opposed to holding onto whatever state they induced.

Google eventually did something like this, which kinda-sorta made it
out in the `absl::StrFormat` library, but it took far too long (and
Google, for many years, explicitly forbade using iostreams in C++ code
for dubious reasons).

More recent languages have introduced happy mediums. I personally like
the way that Rust handles this; `println!` is a macro, and interprets
the format string at compile time, ensuring whatever it specifies
matches its arguments vis types, visibility, safety, etc. But at the
call site, it resembles the concision of printf via a small formatting
language.

        - Dan C.



> I was perhaps the earliest serious experimenter with C++ overloading,
> for a constructive solid geometry package in which arithmetic
> operators were overloaded for matrices and vectors, and boolean
> operators were overloaded for union and intersection of geometric
> objects. I've forgotten how object subtraction (e.g. to drill a hole)
> was represented. Sadly, the symbol vocabulary for  overloading was
> fixed, which meant that two vector products (dot and cross) vied for
> one operator. Joe Condon put me onto an interesting analog of quotient
> and remainder in 3D. The quotient. of two vectors, q=a/b is the ratio
> of the projection of a onto b to b and the remainder r=a%b is the
> component of a perpendicular to b, The usual quotient-remainder
> formula holds::a = q*b + r.
>
> Once, while discussing some detail of overloading, Bjarne remarked
> that he'd like to find an attractive  notation for stream IO, which
> printf certainly is not. << and >> immediately popped into my mind.
> They've been in the language ever since.
>
> Equally casually, there was no discussion about the set of operator
> symbols, so C++ did not come up with a convention for symbol syntax,
> such as  that of Haskell.
>
> Doug


More information about the COFF mailing list