Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
204 views
in Technique[技术] by (71.8m points)

c++ - The effect of `basic_streambuf::setbuf`

My problem is as follows: Martin York claims in this, this, and this answers that one can make a stringstream read from some piece of memory by using basic_stringbuf::pubsetbuf like this:

char buffer[] = "123";
istringstream in;
in.rdbuf()->pubsetbuf(buffer, sizeof(buffer)); // calls basic_stringbuf::setbuf
int num;
in >> num; // reads 123

Unfortunately I dug through the whole standard and couldn't see where it's guaranteed to work. What I see is that's just implementation-defined. In fact on Microsoft's implementation (maybe on others too) this call has no effect.

Here are related quotes I found in the last C++0x draft. For the basic_streambuf::setbuf [streambuf.virt.buffer]:

1 Effects: Influences stream buffering in a way that is defined separately for each class derived from basic_streambuf in this Clause (27.8.1.4, 27.9.1.5).

2 Default behavior: Does nothing. Returns this.

However in the derived classes it seems to leave the behavior implementation-defined. For basic_stringbuf::setbuf it says [stringbuf.virtuals]:

1 Effects: implementation-defined, except that setbuf(0,0) has no effect.

For basic_filebuf::setbuf it says [filebuf.virtuals]:

12 Effects: If setbuf(0,0) [...], the stream becomes unbuffered. Otherwise the results are implementation-defined. “Unbuffered” [...]

And that's it. So as I see it, a valid implementation can ignore these calls completely (for non-null parameters).

Am I wrong? What is the correct interpretation of the standard? Do C++98/03/0x have the same guarantees? Do you have more statistics on which implementations the above code works and on which it does not? How basic_streambuf::setbuf is intended to be used?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I believe it is implementation defined and that you provided the relevant quotes.

For the record, this is what Standard C++ IOStreams and locales, not exactly a recent book I have to admit, has to say on the subject in a section titled "The almost semantic free function - setbuf()" :

The virtual member function setbuf() is a rather peculiar stream buffer member. Its semantics are basically undefined. For string stream buffers, the semantics of setbuf() are implementation-defined, except that setbuf(0, 0) are defined: if setbuf(0, 0) is called on a stream before and I/O has occured on that stream, the stream becomes unbuffered, meaning that characters are directly transported to and from the file system. Otherwise, the results are implementation-defined.

However, the specifications of setbuf() for basic_filebuf and basic_stringbuf hardly impose any requirements on the semantics of setbuf() in other stream buffer types. At best, the general semantics can be defined as device and, in the case of user-defined stream buffer types, implementation-specific.

The lack of any requirements frees you to redefine setbuf() for just about any purpose and in any way that fits into the predefined interface of setbuf().


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...