-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Describe the bug
C++ Standard, [filebuf], paragraph 2 states that:
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 libraryFILEs
So when referring to C standard §7.19.5.3, paragraph 6 states that:
However, output shall not be directly followed by input without an intervening call to the
fflushfunction or to a file positioning function (fseek,fsetpos, orrewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file
One could therefore expect that for a bidirectional std::fstream you could perform stream.seekp(0, std::ios::cur) to satisfy this. In libstdc++ and libc++, this works but this does not work with MSVC STL.
Note that stream.seekp(stream.tellp()) works. So does a +1 and -1 on std::ios:cur.
Command-line test case
#include <fstream>
#include <iostream>
int main() {
std::ofstream init("test.txt");
init << "abcd";
init.close();
char buffer[5] = {};
std::fstream inout("test.txt");
inout.read(buffer, 2);
inout.seekp(0, std::ios::cur); // Should allow switch to write.
inout << "ba";
inout.close();
std::ifstream out("test.txt");
out.read(buffer, 4);
std::cout << buffer << std::endl;
out.close();
}Expected behavior
The output is "abba".
MSVC STL outputs "abcd" - the write operation is completely ignored.
STL version
Microsoft Visual Studio Enterprise 2022
Version 17.5.2
Additional context
C++ standard, [filebuf.virtuals], paragraph 13 states:
Let
widthdenotea_codecvt.encoding(). Ifis_open() == false, oroff != 0 && width <= 0, then the positioning operation fails. Otherwise, ifway != basic_ios::curoroff != 0, and if the last operation was output, then update the output sequence and write any unshift sequence. Next, seek to the new position: ifwidth > 0, callfseek(file, width * off, whence), otherwise callfseek(file, 0, whence)
If I've not misread this: although stream.seekp(0, std::ios::cur) should not touch the output/unshift sequence, it still should call fseek to my understanding.