问题
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 themode
is passed as_IONBF
?Will the buffer be allocated?
Is it OK to pass
0
?
回答1:
The current version (C11) of the C Standard says:
7.21.5.6 The
setvbuf
functionSynopsis
#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 bystream
has been associated with an open file and before any other operation (other than an unsuccessful call tosetvbuf
) is performed on the stream. The argumentmode
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. Ifbuf
is not a null pointer, the array it points to may be used instead of a buffer allocated by thesetvbuf
function273) and the argumentsize
specifies the size of the array; otherwise,size
may determine the size of a buffer allocated by thesetvbuf
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 formode
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);
来源:https://stackoverflow.com/questions/49463798/what-does-the-size-argument-of-setvbuf-mean-for-an-unbuffered-stream