Что означает аргумент размера 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);

Другие вопросы по тегам