This is the mail archive of the
mailing list for the libstdc++ project.
Re: RFC: basic_filebuf supporting non-modal I/O without seekpos
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: David Krauss <potswa at mac dot com>
- Cc: libstdc++ at gcc dot gnu dot org, "Nathan C. Myers" <ncm at cantrip dot org>
- Date: Sat, 18 Sep 2010 10:37:45 +0200
- Subject: Re: RFC: basic_filebuf supporting non-modal I/O without seekpos
- References: <15F914AD-EE57-4F52-9F66-50EB5A329874@mac.com>
> 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).
> Eliminating the modal interface does not mean eliminating the modal implementation. For performance reasons, a filebuf may only have either a get or a put area at any given time. This is necessary to allow direct modification of them by super-speedy functions like sgetc. The current implementation is mostly correct; it is simply missing a few mode transitions. The fix amounts to trapping and correcting the "we're in the wrong state!" errors that currently abort. I believe the attached patch is minimal, and cannot possibly have adverse side-effects. It passes the testsuite on the latest 4.5.2, aside from two bogus tests which do nothing except check for the incorrect behavior by replacing seekpos with sync and verifying failure.
In general terms your approach in the patch below is sensible. We have
of course to make sure that the *current* testsuite passes. Note that,
in general, patches are *always* created first vs current mainline. In
this specific case I don't think the code itself changed much but
please, if you are serious about contributing, make sure to use SVN not
> (I cannot seem to run the performance suite; perhaps that requires 4.6?)
Certainly not, the idea is *much* older than 4.6. Maybe we are missing a
dependency in the Makefile, you may have to run make check at least once
before being able to successfully invoke make check-performance.
> To summarize the changes: Read-mode functions which previously aborted in write-mode call overflow(eof), enter uncommitted mode, and continue. This is OK because the postcondition of overflow(eof) is that the put area is empty. It is trivial to transition to uncommitted mode at that point. Write-mode method overflow, which previously aborted in read mode, sets the file position by calling _M_seek and continues. This is quite like calling seekpos, and I moved some code from seekpos into a new function so that overflow may calculate the parameter for _M_seek.
> So, the new code is entirely guarded by simple Boolean conditions which previously caused a crash-and-burn. No existing state transitions were modified; no new states were created. This patch can alleviate the justified confusion and suspicion of iostreams newbies, so please take it into consideration.
I'll come to the details later. Of course we have also to check what
happens to _M_get_ext_pos in terms of library exports: the rest of the
basic_filebuf instantiations for char and wchar_t should be already
exported, thus very likely you are missing something in the linker
script (which is constantly changing, certainly you cannot patch the
4.5.2 version and assume it's still correct, we are back to my point above).
Please also be ready to provide a ChangeLog entry.