This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: basic_filebuf supporting non-modal I/O without seekpos


On 09/18/2010 10:37 AM, Paolo Carlini wrote:
Hi,
Hi all,

If the user performs a basic_filebuf (or fstream) input operation immediately followed by an output operation, or vice versa, the second operation fails, and that is confusing and non-compliant. The Standard does not describe separate modes for reading and writing, and it certainly doesn't describe seekpos (called by the tellp or tellg methods of fstream) as having the side effect of switching between such modes.

Note however that the semantics described in those sections of the
Standard is *heavily* based on the C library behavior, from the open
modes to the details of seekoff, with fseek at the end, and in the C
Standard those modes are clearly described. Thus I'm not sure to agree
with some of your statements. I think you are more right about seekpos
(which we didn't really discuss so far).

I must say that I have been puzzled by this behaviour and have asked for questions about this situation on this mailing list a few month ago. So I'm reading the bugzilla thread with attention.... In my case, "my error" was trying to use filebuf to have access to a USB device. Usually, I do not try to do both input and output on a regular file. The current behaviour IMHO is puzzling, with things not working silently. From the old standard, it is not so clear to me that the current behaviour is mandated:


P 658 says:

1 The class basic_filebuf<charT,traits> associates both the input sequence and the output
sequence with a file.
2 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.
3 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 indeed there os nothing explicitely written on the seek to change between input and output.

Then the manual of stdio says:

Reads and writes may be intermixed on read/write streams in any order.
Note that ANSI C requires that a file positioning function intervene
between output and input, unless an input operation encounters end-of-
file. (If this condition is not met, then a read is allowed to return
the result of writes other than the most recent.) Therefore it is good
practice (and indeed sometimes necessary under Linux) to put an
fseek(3) or fgetpos(3) operation between write and read operations on
such a stream. This operation may be an apparent no-op (as in
fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect.

But a small test program seems to show that this is not strictly necessary....

#include <stdio.h>

int main() {
char string[20];
FILE* fp = fopen("toto","a+");
fgets(string,10,fp);
fputs("This is a test",fp);
return 0;
}

Certainly works in a way which is not as puzzling as the libstdc++ behaviour (which if I remember
correctly my experience ignores silently the subsequent write).


In conclusion, in my view, the current situation is somewhat confusing (because of the silent behaviour).
I suspect that people have not complained either because reading and write from the same stream is not
used very often or used by people which already know the stdio situation... A google search at the time I encountered
the problem was unsucessful, only posting in this mail list gave me an answer (afterwards, I think I found sthg on the
libstdc++ FAQ, but this was not easy to find).


My reading of the standard (unless it has been changed in the latest versions) does not strictly impose the seek trick to switch between read and write and it seems that current stdio (at least with my limited test) does not enforce this either. So if this is possible to allow it without a performance penalty (or either better removing a performance penalty), that would be great...

It would be interesting to know how other stdc++ libraries behave (or even confirming that stdio does not strictly enforce this rule)... because I also see added value in behaving similarly.
In the worst situation where this is not possible without an ABI change, then I think not mandating the seek if it does not incur performance penalties is the best in terms of user surprises even if it allows program to work fine properly with gnu C++ and not with other compilers (often this is called quality of implementation ;-) )....


My 2 cents on the problem....

Theo.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]