5

C++ iostreams provides control over whether C++ streams must be synchronized with C streams via std::ios_base::sync_with_stdio(). Turning off stream synchronization allows the standard library implementation to use independent unsynchronized buffers for C++ streams and C streams to potentially improve performance.

Why was it considered important to leave a door open for implementers to use separate independent sets of io buffers for C and C++ streams? I don't see how this could potentially improve performance compared to one set of io buffers. Allowing the standard library one set of io buffers at the program level can reduce the number of usually expensive calls to the underlying OS io facilities, but what could be the advantage of two sets of io buffers?

Is there a technical reason that separate buffers for C and C++ streams could benefit performance or is the design just a historical artifact?

Does it somehow have to do with the committee wanting C++ implementors to be able to implement the C++ standard library by building upon their existing C standard library implementations?


I'm looking for more than "the standard says so".

If OS characteristics are necessary to explain the rationale, answers are welcome to use as examples the io facilities provided by a real OS or to explain a hypothetical, but reasonable, OS.


Edit: To clarify, the question is not why synchronizing streams can harm performance. The question is why the C++ standard was designed with the assumption that there may be two sets of io buffers at all and why leaving that possibility open is useful for implementers. std::ios_base::sync_with_stdio() just happens to be the consequence of this assumption.

Praxeolitic
  • 22,455
  • 16
  • 75
  • 126

1 Answers1

4

Unlike some standards which were written to prescribe the behavior of things which hadn't been built yet, the C++ Standard, like the C Standard, was written to describe behaviors of things that already existed. The authors of the Standard wanted to avoid anything that would make it difficult to design a conforming C++ implementation for a platform that would work as well as earlier pre-standard implementations for that platform.

If there were some implementations whose C++ streams supported some additional platform-specific functions not mandated by the Standard, it might not be possible for a conforming C++ implementation to simultaneously support those functions while also using the same buffering constructs as those in C's <stdio.h> package. It may be impossible for the authors of the Standard to avoid either requiring that implementations be incapable of supporting such enhanced semantics or else allowing them to buffer their streams independently from those of <stdio.h>. Given that nothing would preclude particular implementations from guaranteeing that both libraries' streams will use the same buffers whether or not the Standard requires it, the latter choice would have made sense if there was any possibility that a stronger requirement would any useful implementation features.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • This sounds like the right answer, but could you be more specific about what might be impossible or give an example? (It can just be a made up, but reasonable, example.) – Praxeolitic Dec 27 '16 at 20:16
  • @Praxeolitic: As a simple example, someone writing an `` might offer a stream analogue of `ungetc()` which can push back multiple characters even if the input is a pipe or socket. If the `` implementation doesn't offer any such feature, the streams code could keep track of the pushed-back characters and have them appear the next time input is taken from the stream, but there would be no way for such data to appear if code tries to `fread` from the underlying file. – supercat Dec 27 '16 at 21:09
  • It seems like a stretch that the standard intended to accommodate this much deviation from the standard (header named "iostreams.h", non-standard extension to iostreams, no `ungetc()`). Can you point to any evidence that the committee cares about "quasi-conforming" implementations? Plus, if we suppose the iostreams and stdio implementations are somehow fundamentally incompatible, doesn't this make synchronization impossible anyway? – Praxeolitic Dec 27 '16 at 21:26
  • @Praxeolitic: Nothing in the Standard would forbid an implementation from providing a means of pushing an arbitrary amount of data back into a stream. I'm not sure why that would be "quasi-conforming". Given the declaration `extern volatile unsigned foo;` the Standard defines no means by which `foo+foo` could yield an odd number, but in no way precludes the possibility that an implementation might define such a means. – supercat Dec 27 '16 at 21:45