basic_stringbuf
Section: 31.8.2.2 [stringbuf.cons] Status: NAD Submitter: Martin Sebor Opened: 2009-10-29 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [stringbuf.cons].
View all issues with NAD status.
Discussion:
I just came across issue 1204 -- Global permission to move, which seems to address the concern raised by the example in c++std-lib-25030.
IIUC, the example violates the permission to assume that arguments bound to rvalue references are unnamed temporaries granted to implementations by the resolution of issue 1204 - Global permission to move.
I.e., the ostringstream(ostringstream &&rhs)
ctor can leave the rhs
pointers pointing to the newly constructed object's buffer just as
long as the dtor doesn't change or invalidate the buffer. The caller
may not make any assumptions about rhs after the move beyond it being
safe to destroy or reassign.
So unless I misunderstood something, I still think the basic_stringbuf
move ctor is overspecified. Specifically, I think the third sentence
in the Effects clause and the last 6 bullets in the Postconditions
clause can, and IMO should, be stricken.
[ 2010-01-31 Moved to Tentatively NAD after 5 positive votes on c++std-lib. Rationale added below. ]
Rationale:
The sense of 1251 appears to be that the basic_stringbuf
move
constructor offers more guarantees than the minimum. This is true, and quite
correct. The additional words guarantee that the internal buffer has genuinely
transferred from one object to another, and further operations on the original
will not affect the buffer of the newly created object. This is a very
important guarantee, much as we see that a moved-from unique_ptr
is
guaranteed to be empty.
Proposed resolution:
Strike from 31.8.2.2 [stringbuf.cons]:
basic_stringbuf(basic_stringbuf&& rhs);Effects: Move constructs from the rvalue
rhs
. It is implementation-defined whether the sequence pointers in*this
(eback()
,gptr()
,egptr()
,pbase()
,pptr()
,epptr()
) obtain the values whichrhs
had.Whether they do or not,The openmode, locale and any other state of*this
andrhs
reference separate buffers (if any at all) after the construction.rhs
is also copied.Postconditions: Let
rhs_p
refer to the state ofrhs
just prior to this construction and letrhs_a
referto the state ofrhs
just after this construction.
str() == rhs_p.str()
gptr() - eback() == rhs_p.gptr() - rhs_p.eback()
egptr() - eback() == rhs_p.egptr() - rhs_p.eback()
pptr() - pbase() == rhs_p.pptr() - rhs_p.pbase()
epptr() - pbase() == rhs_p.epptr() - rhs_p.pbase()
if(eback()) eback() != rhs_a.eback()
if(gptr()) gptr() != rhs_a.gptr()
if(egptr()) egptr() != rhs_a.egptr()
if(pbase()) pbase() != rhs_a.pbase()
if(pptr()) pptr() != rhs_a.pptr()
if(epptr()) epptr() != rhs_a.epptr()