Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

should std::stringbuf positioning fail after the sequence is fully read?

43 views
Skip to first unread message

Pavel

unread,
Jan 22, 2015, 7:31:40 PM1/22/15
to
Should the code below print 1 or -1? I think -1, but the standard
library implementations I tried printed 1. Am I misreading the standard?

Thanks in advance,
-Pavel

#include <iostream>
#include <sstream>

using namespace std;

int main(int, char*[]) {
const string s(1, 'A');
istringstream iss(s);
char c;
iss >> c;
cout << iss.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in) << endl;
return 0;
}

Öö Tiib

unread,
Jan 23, 2015, 6:13:36 AM1/23/15
to
Why 'std::stringbuf::seekoff' should fail when it is requested to move 'gptr' (that is
at end of input sequence) by 0?

Message has been deleted

Eric Lau

unread,
Jan 23, 2015, 8:19:28 PM1/23/15
to
You might be misunderstanding something. Let's run through main step-by-step:

// Calls operator>>(basic_istream, char&) (simplified template) which does a few things including an sbumpc/adds one to the offset and updates c with character from the current position of the stream; position is now 1 since iss's position count initializes to 0
iss >> c;

// iss.rdbuf() returns the streambuf followed by pubseekoff
// pubseekoff as called here offsets 0 from the way parameter (ios_base::cur in this case), with a mode of ios_base::in; cur is at 1 due to the offset modification from the previous line, and 1 offset by 0 == 1
cout << iss.rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in) << endl;

If you were to make the string s("AB") and use two lines of iss >> c, you would get 2 in your cout. If you never called operator>>, you should be returned a 0 (as the istringstream is constructed with position 0). If you used ios_base::out, you should expect -1.

pubseekoff called seekoff directly, and seekoff is overridden in sstream. Within it, there's a check for if ios_base::int && pptr() != 0 (pptr being the read position). Since your case satisfies that condition, it picks up your position as expected. Had you set your openmode to ios_base::out, you would have taken the condition ios_base::out && gptr() != 0, resulting in false and dropping down to the failed value.

I know I circled around a little, but I hope this helps a anyway. Feel free to ask about any parts that you're still unclear about.

Pavel

unread,
Jan 23, 2015, 10:21:28 PM1/23/15
to
My understanding of 27.8.2.4-11 is that, regardless of by how much
std::stringbuf::seekoff is requested to move 'gptr', it should fail, in
particular, if (quoting):

"newoff + off refers to an uninitialized character (as defined in 27.8.2.3
paragraph 1)"

for ios_base::cur operation and ios_base::in openmode, newoff == gnext - gbeg
that is 1 in my example.
off is 0, so newoff + off is 1. I believe that newoff + off refers to
uninitialized characters because, as defined in 27.8.2.3. Quoting:

"If the basic_stringbuf was created only in input mode, the resultant
basic_string contains the character sequence in the range [eback(),egptr())"

Note that the character at egptr() is excluded. As for egptr(), it is equal to
eback() + s.size() as per 27.8.2.3-3 which applies because the initializing
effect of the constructor used in my example is that of calling str(const
string&), as per 27.8.2.1-3. That is, in my example, egptr() == eback() + 1.

As we established that the positioning operation should fail,
stringbuf::seekoff should return pos_type(off_type(-1)) as per 27.8.2.4-11.

What am I missing?

-Pavel


Pavel

unread,
Jan 23, 2015, 10:44:47 PM1/23/15
to
Thanks Eric. Your explanation matches the stringbuf::seekoff() implementations I
dealt with. My question, however, was about what should happen in accordance
with the Standard (please see my answer to 嘱 Tiib for gory details). That is to
say, I want to know whether I can expect the present behavior kept in the future
(supposedly as or more standard-compliant) versions of my C++ implementation or
I need to design a workaround.

-Pavel


0 new messages