2473. basic_filebuf's relation to C FILE semantics

Section: 30.9.2.4 [filebuf.virtuals] Status: C++17 Submitter: Aaron Ballman Opened: 2015-02-09 Last modified: 2017-07-30

Priority: 2

View all other issues in [filebuf.virtuals].

View all issues with C++17 status.

Discussion:

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 Standard C library FILEs. One of the restrictions placed by C is on the behavior of a stream that is opened for input and output. See the C99 standard, 7.19.5.3p6 for more details, but the gist is that when opened in update mode, reads and writes must have an intervening file positioning or flushing call to not trigger UB.

30.9.2.4 [filebuf.virtuals] p13 specifies that basic_filebuf::seekoff() calls std::fseek(). However, there is no mention of std::fseek() in basic_filebuf::seekpos(), and no mention of std::fflush() in basic_filebuf::sync(), which seem like an oversight.

Previous resolution [SUPERSEDED]:

This wording is relative to N4296.

  1. Change 30.9.2.4 [filebuf.virtuals] p16 as follows [Editorial note: A footnote referring to fseek is not needed, because this is already covered by the existing footnote 334]:

    -16- Alters the file position, if possible, to correspond to the position stored in sp (as described below). Altering the file position performs as follows:

    1. if (om & ios_base::out) != 0, then update the output sequence and write any unshift sequence;

    2. set the file position to sp as if by calling std::fseek(file, sp, SEEK_SET);

    3. if (om & ios_base::in) != 0, then update the input sequence;

    where om is the open mode passed to the last call to open(). The operation fails if is_open() returns false.

  2. Change 30.9.2.4 [filebuf.virtuals] p19 as follows and add a new footnote that mimics comparable footnotes in 30.9.2.3 [filebuf.members] and 30.9.2.4 [filebuf.virtuals]:

    -19- Effects: If a put area exists, calls filebuf::overflow to write the characters to the file, then flushes the file as if by calling std::fflush(file) [Footnote: The function signature fflush(FILE*) is declared in <cstdio> (27.9.2).]. If a get area exists, the effect is implementation-defined.

[2015-05, Lenexa]

Aaron provides improved wording by removing the params from std::fseek() due to the concerns regarding the parameters on systems where fseek uses 32-bit parameters.

Second wording improvement, replacing the new one see below. It

  1. drops the std::

  2. drops the footnote for fflush

  3. replaces fseek with fsetpos

Previous resolution [SUPERSEDED]:

This wording is relative to N4431.

  1. Change 30.9.2.4 [filebuf.virtuals] p16 as follows [Editorial note: A footnote referring to fseek is not needed, because this is already covered by the existing footnote 334]:

    -16- Alters the file position, if possible, to correspond to the position stored in sp (as described below). Altering the file position performs as follows:

    1. if (om & ios_base::out) != 0, then update the output sequence and write any unshift sequence;

    2. set the file position to sp as if by a call to std::fseek;

    3. if (om & ios_base::in) != 0, then update the input sequence;

    where om is the open mode passed to the last call to open(). The operation fails if is_open() returns false.

  2. Change 30.9.2.4 [filebuf.virtuals] p19 as follows and add a new footnote that mimics comparable footnotes in 30.9.2.3 [filebuf.members] and 30.9.2.4 [filebuf.virtuals]:

    -19- Effects: If a put area exists, calls filebuf::overflow to write the characters to the file, then flushes the file as if by calling std::fflush(file) [Footnote: The function signature fflush(FILE*) is declared in <cstdio> (27.9.2).]. If a get area exists, the effect is implementation-defined.

Proposed resolution:

This wording is relative to N4431.

  1. Change 30.9.2.4 [filebuf.virtuals] p16 as follows:

    -16- Alters the file position, if possible, to correspond to the position stored in sp (as described below). Altering the file position performs as follows:

    1. if (om & ios_base::out) != 0, then update the output sequence and write any unshift sequence;

    2. set the file position to sp as if by a call to fsetpos;

    3. if (om & ios_base::in) != 0, then update the input sequence;

    where om is the open mode passed to the last call to open(). The operation fails if is_open() returns false.

  2. Change 30.9.2.4 [filebuf.virtuals] p19 as follows:

    -19- Effects: If a put area exists, calls filebuf::overflow to write the characters to the file, then flushes the file as if by calling fflush(file). If a get area exists, the effect is implementation-defined.