setvbuf() - size parameter when buf is NULL

2019-07-15 07:10发布

问题:

It seems that when I run the following code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv)
{
    int i=0;

    setvbuf(stdout, NULL, _IOLBF,0);

    while (1)
            printf("%d ",i++);

    return 0;
}

it prints in chunks of 1024 chars, no matter the size I define for setvbuf(). The question is is if size affects somehow in this case and where is the definition for 1024 chars is coming from.

回答1:

I don't know how you identified 1024 but it's probably BUFSIZ. BUFSIZ is defined in stdio.h.

If buf is NULL, then the stdio library automatically allocates a buffer for use with stream (unless we select unbuffered I/O).

EDIT

Here's something glibc says:

Macro: int BUFSIZ The value of this macro is an integer constant expression that is good to use for the size argument to setvbuf. This value is guaranteed to be at least 256.

The value of BUFSIZ is chosen on each system so as to make stream I/O efficient. So it is a good idea to use BUFSIZ as the size for the buffer when you call setvbuf.

EDIT 2

@larsmans is right. I looked at how setvbuf is implemented and it ignores a call when asking for line buffering and presenting a NULL buf. Now, stdout is no ordinary file, it's attached to a terminal. So, heading over to pixelbeat

  • Buffer size only directly affects buffered mode
  • The default size like the kernel is based on the page size (4096 bytes on my system)
  • if stdin/stdout are connected to a terminal then default size = 1024;
    else size = 4096


回答2:

According to the (draft) C standard,

If buf is not a null pointer, the array it points to may be used instead of a buffer allocated by the setvbuf function and the argument size specifies the size of the array; otherwise, size may determine the size of a buffer allocated by the setvbuf function. [Emphasis added.]

So, assuming you measured correctly, it seems like Glibc is free to do as it pleases when buf is null, and it gives you a 1kB buffer. Since you never write a newline, line buffering has no effect and the behavior is similar to full buffering.



回答3:

The size probably doesn't have much effect for a NULL buf pointer.

However, you are still requesting buffered output with _IOLBF Try _IONBF instead.

http://en.wikipedia.org/wiki/Setvbuf



标签: c glibc stdio