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);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…