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
244 views
in Technique[技术] by (71.8m points)

c - What does the size argument of setvbuf mean for an unbuffered stream?

The function setvbuf() can be used to make a stream unbuffered:

#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
  • What does the value of the size argument mean when the mode is passed as _IONBF?

  • Will the buffer be allocated?

  • Is it OK to pass 0?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

The current version (C11) of the C Standard says:

7.21.5.6 The setvbuf function

Synopsis

   #include <stdio.h>
   int setvbuf(FILE * restrict stream,
               char * restrict buf,
               int mode, size_t size);

Description

The setvbuf function may be used only after the stream pointed to by stream has been associated with an open file and before any other operation (other than an unsuccessful call to setvbuf) is performed on the stream. The argument mode determines how stream will be buffered, as follows: _IOFBF causes input/output to be fully buffered; _IOLBF causes input/output to be line buffered; _IONBF causes input/output to be unbuffered. If buf is not a null pointer, the array it points to may be used instead of a buffer allocated by the setvbuf function273) and the argument size specifies the size of the array; otherwise, size may determine the size of a buffer allocated by the setvbuf function. The contents of the array at any time are indeterminate.

Returns

The setvbuf function returns zero on success, or nonzero if an invalid value is given for mode or if the request cannot be honored.

The use of the conditional tense gives a lot of flexibility for the library author as to how to implement setvbuf().

Steve Summit arguments this way:

Clearly size should be ignored if mode is passed as _IONBF, and clearly 0 is the appropriate value to pass. (That is, if you passed any number other than 0, it would still be ignored, and nothing would be allocated, but the call would look horribly misleading.) But two different man pages I've just looked at don't come out and say this explicitly.

The C Standard does indeed allow for size to be ignored for all cases and it does make sense that it be ignored for the unbuffered case.

I found an alternative that makes sense too: setvbuf() could still specify the buffer to be used by the stream output functions, static or allocated, as long as the stream functions do not keep any unflushed output in it when they return. For example, printf could use this buffer to compose its output and flush it by chunks. The C Standard does not specify that unbuffered streams use a system call for each byte written to the output stream's system handle. These are implementation details beyond the scope of the Standard.

If setvbuf() indeed tries to allocate size bytes and fails, it may return a non zero value and not make the stream unbuffered. An unexpected behavior that would still be conformant. Try setvbuf(stdout, NULL, _IOFBF, SIZE_MAX);


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

...