This is the mail archive of the
mailing list for the libstdc++ project.
Re: Why fixing 9533 doesn't fix 7744: revealed!
On Wed, Mar 05, 2003 at 06:08:55PM -0600, Loren James Rittle wrote:
> In article <3E666428 dot 8040004 at unitus dot it> Paolo, the new wonder bug
> fixer and performance enhancer, writes:
> >> The call to xsgetn is at the wrong level of abstraction. It keeps
> >> trying until it gets n characters, or EOF. You want to call ::read()
> >> in underflow(), and just go with as many characters as it returns.
> >> (If it returns -1 and errno is EINTR you would call it again.)
> >> Then, get rid of that isatty()!
> I agree with the above in theory. And, I would fully support seeing
> it in practice whenever ios::sync_with_stdio(false) had been called.
> However there are a few issues to consider (I'm sure you have already
> spotted them, but I want them filed for the record before you generate
> a patch): underflow()'s implementation is currently declared where it
> is *not* legal to put direct calls to ::read(). IMHO, you will have
> to rearrange its body or delegated body to appear in
> config/io/bla-bla. Nathan/Benjamin, confirm that you'd agree with
I think so. But I think it's pointless to pretend that a usable
iostreams library can be constructed on top of the fatally limited FILE
abstraction. For environments where it seems as if there's no choice
(but, where did they get their FILEs?) we might as well use fread().
Users there can call setbuf(0,0) if they want reasonable interactive
What was the reason that you chose a one-character buffer over making
it entirely unbuffered? They seem equivalent, but having three modes
seems unnecessarily complicated.
> Either way, I'd agree that the standard says nothing about
> underflow() having to be implemented in terms of xsgetn(). In
> retrospect, that was clearly an unfortunate implementation choice.
> I.e. good catch Nathan. All the times I've hacked on that code, I
> took it as a given that underflow had to be implemented in such terms!
> > Ok (too bad that I learned how to use some autoconf machinery for
> > something which was not going to last much ;)
> > To be honest, at the time Loren envisaged using read (and, at the time
> > I didn't realy understand that :) but had also some perplexities:
> Mentioning my name in a thread will *not* get me involved beyond
> commentary... ;-)
> > >... POSIX IO. Someone skilled in the art could construct a
> > >well-performing implementation of __basic_file<char>::xsgetn() that
> > >could return short-reads [e.g. fread() (stdio) will only return a
> > >short-read on error or EOF whereas read() (POSIX) will short-read
> > >based on the current line discipline]. It is possible that this
> > >alternate implementation should only be used when
> > >ios::sync_with_stdio(false) was called (since the only portable way to
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > >share stdio buffers is to make stdio calls).
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > Do you believe I can go ahead and safely change the underlying
> > implementation of xsgetn to use read instead of fread?
> For all cases? No, but I'm willing to be shown how. If you can find
> a way to unconditionally change the underlying implementation, then
> feel free to undo all the hacks we installed to fix various corner
> cases. (i.e. I can't disagree with Nathan's assessment.) OTOH, I
> feel it would be a clear win to improve the
> ios::sync_with_stdio(false) case through various means even if the
> ios::sync_with_stdio(true) case continues to require special hacks.
Yes, this the path forward: make the native mode fast and clean, and
make the hack mode (just barely) work. I like the idea of two
entirely different objects, one a hack job on stdio and the other
purely POSIX-native, and sync_with_stdio(false) plugs the latter
in in place of the former.
One thing to get away from is this idea that it's OK for C++ to be a
second-class citizen, dependent on C for its low-level access. C++
is not a bag on C, it's a whole other language. It has to be link-
compatible with C, but besides that it should stand alone. The
libstdc++.so should talk directly to the OS. Non-POSIX users who want
the library to perform well for them may supply patches making
similarly low-level access for their platforms. We shouldn't
(e.g.) introduce thread-unsafety just to avoid the need for low-level
access, or introduce undue complexity in trying to perform well where
we don't have low-level access.
Our C++ locale code should read the same files as the C library does,
instead of calling C library functions and trying to patch up after.
For non Glibc systems, POSIX provides tools to extract the files to
a standard format; the library installer can use these to generate
corresponding files for our library's use, in Glibc's format. That
way the code to read the files may be common to all POSIX platforms.
Then, users of non-POSIX platforms can send utilities to convert their
own locale files' formats (or make do with just the "C" locale).
On many platforms we can achieve better integration with stdio by
deriving streambuf from FILE and making the setg/setp/eback/gptr/
egptr/pptr/epptr family of functions refer to the same (inherited)
struct members as do getc and putc do, and make underflow and
overflow use the same file descriptor member. There's just not
so much variation in stdio implementations.
ncm-nospam at cantrip dot org