When using a std::fstream
you can read and write to the file. I'm wondering if there is any part of the C++ standard stating the requirements for switching between read & write operations.
What I found is:
The restrictions on reading and writing a sequence controlled by an object of class
basic_filebuf<charT, traits>
are the same as for reading and writing with the C standard libraryFILE
s.
In particular:— If the file is not open for reading the input sequence cannot be read.
— If the file is not open for writing the output sequence cannot be written.
— A joint file position is maintained for both the input sequence and the output sequence
So according to only the bullet points if I open a std::fstream
, read 5 bytes, then write 2 bytes the new bytes will end up at position 6 & 7: First 2 conditions are met and due to the "joint file position" the read will advance the write position by 5 bytes.
However in practice intermediate buffers are used instead of directly calling fread
/fwrite
for every single byte. Hence the 5-byte-read could read 512 bytes from the underlying FILE
and if that is not accounted for during the write that will end up at position 513 not 6 in the above example.
And indeed libstdc++ (GCC) does correct the offsets: https://github.com/gcc-mirror/gcc/blob/13ea4a6e830da1f245136601e636dec62e74d1a7/libstdc%2B%2B-v3/include/bits/fstream.tcc#L554
I haven't found anything similar in libc++ (Clang) or MS STL, although MS "cheats" by using the buffers from the FILE*
inside the filebuf
, so it might "work" there.
Anyway: For the C functions I found that switching between read & write requires a seek or flush (after write): https://en.cppreference.com/w/c/io/fopen
So does the part "The restrictions [...] of class basic_filebuf<charT, traits>
are the same as [...] with the C standard library" may also be applied to this, so a seekg
, seekp
, tellg
, tellp
or sync
is required to switch between operations?
Context: I maintain a library providing an (enhanced) filebuf
class and not checking if the FILE*
position needs to be adjusted to account for buffering due to potential read/write switches without seek/sync saves a potentially expensive conditional. But I don't want to deviate from the standard requirements to not break users expecting a drop-in replacement.