4 ms·
In the stdio implementations that don't support free intermixing of reads and writes the issue typically is that there is only one buffer for both reading and w
by cryptonector 2y ago
In the stdio implementations that don't support free intermixing of reads and writes the issue typically is that there is only one buffer for both reading and writing. You have to reset the buffer in order to switch from reading to writing or vice-versa, else you will have a dirty, non-empty buffer that does not correspond. The functions `fflush()`, `fseek()`, `rewind()`, and `fsetpos()` happen to clear the buffer, which is why you have to use them before switching from reading to writing or vice-versa!
Without an indicator in `struct FILE` of whether the last operation was a read or a write, the stdio implementation has no way to detect the problem and correct the situation by automatically flushing and resetting the buffer, say. An alternative would be to have two buffers, naturally. But you can see how a pre-update version could be trivially made to support update modes without adding a second buffer or automatic buffer flushing. And that's almost certainly what happened when update mode was added. My guess is someone got bitten by that and then the maintainer decided to just document the problem rather than fix it, probably because by then fixing the problem was hard.
- fweimer 2y agoHistorically, before mandatory locking, getc and putc have been implemented as macros, and an extra check for stream state likely mattered from a performance perspective. To avoid the extra check, you don't actually need two buffers, just separate buffer pointers for reading and writing. (This is probably how most libcs implement this today.) I suppose memory was really scarce back then.
- cryptonector 2y agoSeparate non-overlapping pointers into one buffer is not that different from two buffers, notionally, but yeah.
- fweimer 2y agoThe idea is that for the non-active mode, the current/end pointers are equal, signifying that the buffer is exhausted. This forces entering the slow path, where the mode can be switched. I don't think an implementation with two active, non-empty buffers is all that useful because you can't tell which buffer's progress should be used for the file pointer adjustment in ftell.
- cryptonector 2y agoI get that. One buffer that can be maximized by the path that most needs it (read or write). I'm just saying that notionally it's two independent buffers, which solves the problem of not having to force a buffer flush between mode change. > I don't think an implementation with two active, non-empty buffers is all that useful because you can't tell which buffer's progress should be used for the file pointer adjustment in ftell. Oh interesting. The other problem is that two buffers reduces memory utilization.