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]

[RFC] libstdc++/9404 or weird stringbuf internals


Hi everyone.

In the last few days I worked hard on this PR, which however
still resists my attempts to fix it in a simple and neat way...

I'd appreciate some help in my attempt to understand the inner
working of v3 stringbuffers.

This is the issue. Consider a sequence of plain sputc without
nothing in between:

   sputc('a');
   sputc('b');
   ...

Upon the first one, overflow is called since there isn't an
allocated string. Therefore overflow allocates one, then calls
sputc again, as prescribed by the standard (well, not really, in
fact it does *this->_M_out_cur = traits_type::to_char_type(__c);
which is not the same thing, but this is a minor nit which
could be easily fixed with some performance implications...).

Anyway, at this point _M_out_cur  == _M_out_end, since the current
write position (_M_out_cur) is one-char-past the end (_M_out_end).
(now _M_out_cur = _M_out_beg + 1)

Therefore, basing on the standard, we expect that upon the second
sputc, overflow will be called once more: on the contrary, this
does *not* happen, since sputc calls overflow only if
_M_out_buf_size() is zero, which, for stringbuf (allocated buffer)
evaluates to:

   _M_out_beg + _M_buf_size - _M_out_cur

and _M_buf_size is now ~1100.

Bummer!

It looks like there is something basically non-ISO confroming in
the logic used by sputc (in the stringbuf case) for choosing if
calling or not overflow.

To repeat, it seems that, in this buffered case, whereas v3
_M_out_beg has the semantics of the ISO pback(), _M_out_cur is
not really pptr() and _M_out_end is not really epptr().

We call overflow when the underlying buffer string is too short,
not when along the actual sequence being written pptr() == epptr(),
since we know that, in fact, there _is_ space free in the underlying
string and we can safely proceed.

But, if someone (Pétur ;) wants to see overflow called during
a sputc which starts with pptr() == epptr()...

What to do, then?

I could try changing both _M_out_buf_size() and overflow
to the effect of calling overflow for each sputc of a sequence.
This has a price, however, in terms of virtual functions called.

Is this the only standard-conforming possibility?

Perhaps I misread the standard and it is not really compulsory
to call overflow whenever pptr() == epptr()?

Please help!

Thanks,
Paolo.


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