c - setvbuf 的大小参数对于未缓冲的流意味着什么?



函数setvbuf()可用于使流无缓冲:

#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
  • mode作为_IONBF传递时,size参数的值是什么意思?

  • 缓冲区会被分配吗?

  • 通过0可以吗?

C标准的当前版本(C11)说:

7.21.5.6setvbuf函数

概要

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

描述

只有在stream指向的流与打开的文件相关联之后,以及在流上执行任何其他操作(对setvbuf的不成功调用除外)之前,才能使用setvbuf函数。参数mode确定如何缓冲流,如下所示:_IOFBF导致输入/输出完全缓冲;_IOLBF导致输入/输出被线路缓冲;_IONBF会导致输入/输出未缓冲。如果buf不是空指针,则可以使用它指向的数组代替由setvbuf函数273)分配的缓冲区,并且参数size指定数组的大小;否则,size可以确定由setvbuf函数分配的缓冲区的大小。数组在任何时候的内容都是不确定的。

返回

setvbuf函数在成功时返回零,如果为mode提供无效值或无法接受请求,则返回非零值。

条件时态的使用为库作者在如何实现setvbuf()方面提供了很大的灵活性。

史蒂夫峰会这样论证:

显然,如果mode作为_IONBF传递,则应忽略size,并且显然0是要传递的适当值。 (也就是说,如果您传递了 0 以外的任何数字,它仍将被忽略,并且不会分配任何内容,但调用看起来会非常具有误导性。但是我刚刚看过的两个不同的手册页并没有出来明确地说出来。

C 标准确实允许在所有情况下忽略size,并且在未缓冲的情况下忽略它是有意义的。

我找到了一个也有意义的替代方案:setvbuf()仍然可以指定流输出函数要使用的缓冲区,静态或分配,只要流函数在返回时不保留任何未刷新的输出。例如,printf可以使用此缓冲区来组合其输出并按块刷新它。C 标准指定未缓冲流对写入输出流的系统句柄的每个字节使用系统调用。这些是超出标准范围的实施细节。

如果setvbuf()确实尝试分配size个字节并失败,则它可能返回非零值,并且不会使流未缓冲。仍符合的意外行为。试试setvbuf(stdout, NULL, _IOFBF, SIZE_MAX);

最新更新