This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Strange stream behaviour
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: Re: Strange stream behaviour
- From: Nathan Myers <ncm at nospam dot cantrip dot org>
- Date: Sun, 7 Oct 2001 02:30:41 -0700
- References: <uy9morg36.fsf@yandex.ru>
- Reply-To: libstdc++ at sourceware dot cygnus dot com
On Sat, Oct 06, 2001 at 06:35:57PM +0400, Roman Belenov wrote:
> I've found that simple copy program
> #include <iostream>
> int main()
> { int ch; while( (ch = std::cin.get()) != EOF ) std::cout.put(ch); }
>
> duplicates pieces from input, first occurence being about
> position 3000 in the input stream.
There is no reason to expect the program to work. In particular, the
function cin.get() can never return EOF under any circumstances. EOF
is an int constant, where cin.get() can only return character values.
The loop termination condition for such a program must check the
stream state, not the result of cin.get().
Gospodin Belenov is evidently confusing istream::get() with
streambuf::sbumpc(), the latter of which is more analogous with the
C library macro getc(FILE*). A plausible replacement for his program
that should be comparable to the familiar C program might be
#include <iostream>
int main()
{
std::ios_base::sync_with_stdio(false); // do this in all C++ programs
std::streambuf* ibuf = std::cin.rdbuf();
std::streambuf* obuf = std::cout.rdbuf();
int ch;
while( (ch = ibuf->sbumpc()) != EOF )
obuf->sputc(ch);
return 0;
}
Unfortunately the implementation of streambuf in release 3.0.1 (and
CVS current) are unnecessarily inefficient, so that the above program
is about 27 times slower than it should be, in my tests.
Measures to fix it would include inlining streambuf members sbumpc()
and sputc(), and removing the unnecessary test in sbump() for a null
_M_in_cur. (Those changes alone won't make much difference until
the real problem, which I haven't identified yet, gets fixed.)
Nathan Myers
ncm at cantrip dot org