Question Details

No question body available.

Tags

c++ language-lawyer buffer fstream api-design

Answers (1)

June 15, 2025 Score: 2 Rep: 75,135 Quality: Medium Completeness: 60%

Stroustrup explains in his book "The design and evolution of C++" one of the key design rules:

Always provide a transition path: C++ must grow gradually to serve its users and benefit from their feedback. This implies that great care must be taken to ensure that older code continues to work. (...) The general strategy for eliminating an unsafe (..) language feature is to first provide a better alternative, then recommend that people avoid the old feature or technique, and only years later - if at all - remove the offending feature.

For decades, people used to work with char based streams for file io (in the first edition of "The C++ programming language", when templates did not even exist, streams where already defined with char*). There are now billions of lines of code out there that rely on this assumption, and nobody really wants to review it all if it is not absolutely necessary. I think this weights heavily on any decision to change the standard library for the sake of definitions.

The use of unsigned char in the definition of the object representation is already relatively old. It was introduced with C++11. In C++98 it was still referred to " char or unsigned char ". So, indeed it would be tempting to align the standard library. But there are plenty of uses cases where people use really expect streams to deal characters. It would then be difficult to distinguish when to use the one rather than the other. (I also personally believe it doesn't change so much our reality, to write binary chars or unsigned chars, and that as long as you don't do math on them or print them as integers; but perhaps I'm too naive).

Annoter important design principle that Stroustrup gives :

C++'s evolution must be driven by real problems: (...) The right motivation for a change to C++ is for several programmes to demonstrate how the language is insufficiently expressive for their projects. (...)

Here, I would argue that the language expressivity is sufficient, and rather than changing the definition of istream and ostream, if you think it's essential, nothing prevents you from fully using the available template arguments, for example:

// define your own serialization stream types: using slzostream = basicostream; using slziostream = basiciostream;