`<fstream>`: seeking 0 with std::ios::cur ignored with bidirectional streams
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided command-line test case and inspect the std::fstream seekp and basic_filebuf positioning behavior for bidirectional streams. Compare seekp(0, std::ios::cur) with seekp(stream.tellp()) and nonzero relative seeks; done means the sample produces "abba" and the positioning operation correctly permits the following write.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100