Re: Odd ostringstream::str behavior?
Alberto Ganesh Barbati wrote:
lindahlb@hotmail.com ha scritto:
The output should be "test passed" everytime a line is pressed, no
matter what. However, with the implicit constructor of "ostr", the
output is "test " every time. Passing in an initial string changes
whether or not ostringstream::str() ALWAYS returns an empty string,
despite data being streamed to it after construction. Is this a broken
implementation (gcc 3.4.6)?
This program has undefined behavior, so whatever output you get is
correct. The sources of undefined-ness are the two calls to seekg/seekp.
In fact they both eventually call basic_stringbuf::seekpos, and its
definition requires that the position must have been obtained by "a
previous successful call to one of the positioning functions(seekoff,
seekpos, tellg, tellp)" otherwise the effect is undefined
(?27.7.1.3/14). As you are passing 0, the requirement has not been
satisfied.
This is true, but...
In at least one implementation (g++), and probably a lot of
others, tellg() will return 0. (Or rather something that will
convert to zero, and to which 0 will convert.)
How do you fix that? Two ways:
[...]
2) use a tellp/tellg to get pos_type to the beginning of the stream and
use that:
in function main, just after the creation of streams:
istream::pos_type istart = istr.tellp();
ostream::pos_type ostart = ostr.tellg();
in function copy:
istr.seekg(istart);
ostr.seekp(ostart);
If you try any of this two approaches you get well-defined
behavior, but... well, the result will be *exactly* the same
as the one you described! (Which therefore is the *correct*
result!)
No it's not. She'll get the same results, but only due to a bug
in the library. (Well, she'll also get the same results because
g++ returns 0 from the tellp(), so it cannot distinguish whether
her 0 came from tellp() or not, and so must handle it
correctly.) You can still legally position at the start of an
empty stream. In general, positionning at the end of file
position is legal; why should this be an exception. (FWIW: g++
has accepted it as an error.)
That's because when you initialize ostr with the default
constructor, no array will be allocated (27.7.1.1/2).
I don't see this in my copy of the standard (the latest draft).
The cited paragraph says simply that there is a post-condition
of `str() == ""'.
The absence of an output sequence makes seekoff() on ostr fail
(27.7.1.3/11).
That looks like a bug in the standard. Seeking should obey the
same half-open interval semantics as are used in the STL. You
can seek to one past the end of the sequence, but you cannot
read from the position. (This is the way a file system seek has
worked on all non-Unix systems I've worked on. Unix has
somewhat wierd semantics for seeking beyond the end of file.)
So according to which of the two approaches above you
followed, either the call to seekp(0, beg) or the call to
tellp() fail (both these calls eventually call seekoff()).
Morale: don't try to reposition an empty string-based stream.
In other words, you're saying that you cannot risk a seek if you
don't know whether the sequence is empty or not. If that's the
case, it's an error in the standard.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]