This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Why fixing 9533 doesn't fix 7774: revealed!
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Cc: Nathan Myers <ncm at cantrip dot org>
- Date: Wed, 05 Mar 2003 14:13:01 +0100
- Subject: Why fixing 9533 doesn't fix 7774: revealed!
Hi,
seriously, after a little more gdb along the lines suggested
by Nathan, I know why and I'd like to ask your opinion about
what should we actually do now that we know what's going on.
This is 7744 testcase:
void f2()
{
cout
<< "\n:: f2() ::\n"
<< "Type in the characters 'abc' and press <ENTER>: ";
cin.peek();
cout
<< "The number of unread characters should be 4 (a, b, c, \\n): "
<< cin.rdbuf()->in_avail()
<< '\n';
}
As Nathan explained, in_avail shouldn't call showmanyc but in
fact it does. Why?
Because after the in.peek(), egptr == gptr! Indeed, in.peek()
calls sgetc(), which calls underflow(), which does:
__elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
_M_buf_size);
__ilen = __elen;
if (0 < __ilen)
{
_M_set_determinate(__ilen);
if (__testout)
_M_out_cur = _M_in_cur;
__ret = traits_type::to_int_type(*_M_in_cur);
if (__bump)
_M_in_cur_move(1);
else if (_M_buf_size == 1)
{
// If we are synced with stdio, we have to unget the
// character we just read so that the file pointer
// doesn't move.
_M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
_M_set_indeterminate();
}
}
There are no chances that 4 chars are put in the buffer (stdio is synced
and _M_buf_size == 1) but we expect at least one!
That single char _is_ in fact put into the buffer, but, since
_M_buf_size == 1
the char is unget and _M_set_indeterminate called, which basically reset
all the get area pointers to _M_buf and the information on the char present
in the buffer ends up _not_ being propagated (as egptr == gptr + 1) to
in_avail.
So, a few question:
1- Is that _M_set_indeterminate() call really necessary for other reasons?
2- Is it ok to have _M_buf_size == 1 when synced with stdio?
Thanks,
Paolo.