Что означает аргумент размера setvbuf для небуферизованного потока?
Функция setvbuf()
может быть использован, чтобы сделать поток небуферизованным:
#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
Какое значение имеет
size
аргумент значит, когдаmode
передается как_IONBF
?Будет ли выделен буфер?
Это нормально, чтобы пройти
0
?
1 ответ
Текущая версия (C11) стандарта C гласит:
7.21.5.6.
setvbuf
функцияконспект
#include <stdio.h> int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
Описание
setvbuf
Функция может использоваться только после того, как поток, на который указываетstream
был связан с открытым файлом и перед любой другой операцией (кроме неудачного вызоваsetvbuf
) выполняется в потоке. Аргументmode
определяет, как поток будет буферизован, следующим образом:_IOFBF
заставляет ввод / вывод быть полностью буферизованным;_IOLBF
заставляет ввод / вывод быть буферизованным строкой;_IONBF
вызывает ввод / вывод для буферизации. Еслиbuf
не является нулевым указателем, массив, на который он указывает, может использоваться вместо буфера, выделенногоsetvbuf
функция 273) и аргументsize
указывает размер массива; иначе,size
может определить размер буфера, выделенногоsetvbuf
функция. Содержимое массива в любое время является неопределенным.Возвращает
setvbuf
функция возвращает ноль в случае успеха или ненулевое значение, если дляmode
или если запрос не может быть выполнен.
Использование условного времени дает большую гибкость для автора библиотеки в том, как реализовать setvbuf()
,
Стив Саммит рассуждает так:
очевидно size
следует игнорировать, если mode
передается как _IONBF
и четко 0
является подходящим значением для передачи. (То есть, если вы передадите любое число, отличное от 0, оно все равно будет проигнорировано, и ничего не будет выделено, но вызов будет выглядеть ужасно вводящим в заблуждение.) Но две разные справочные страницы, на которые я только что посмотрел, не выходят и скажи это явно.
Стандарт C действительно допускает size
быть проигнорированным для всех случаев, и имеет смысл игнорировать его для небуферизованного случая.
Я нашел альтернативу, которая тоже имеет смысл: setvbuf()
может по-прежнему указывать буфер, который будет использоваться функциями вывода потока, статический или выделенный, при условии, что функции потока не сохраняют в нем никакого незаполненного вывода при возврате. Например, printf
мог бы использовать этот буфер, чтобы составить его вывод и очистить его кусками. Стандарт C не указывает, что небуферизованные потоки используют системный вызов для каждого байта, записанного в системный дескриптор выходного потока. Это детали реализации, выходящие за рамки стандарта.
Если setvbuf()
действительно пытается выделить size
байты и сбои, он может возвращать ненулевое значение и не делать поток небуферизованным. Неожиданное поведение, которое все равно будет соответствовать. Пытаться setvbuf(stdout, NULL, _IOFBF, SIZE_MAX);