Обоснование системных вызовов, которые позволяют запрос size_t, но результат только ssize_t? - PullRequest
8 голосов
/ 02 мая 2011

Рассмотрим:

ssize_t write(int fd, const void *buf, size_t count);

Результат должен быть подписан для учета -1 в случае ошибки и т. Д., И поэтому он равен ssize_t. Но зачем тогда допускать, чтобы запрос был размером без знака (вдвое больше), когда результат запроса больше ssize_t не определен?

Есть ли существенная оптимизация в ядре за счет отсутствия проверки на подпись параметра count? Или что-то еще?

Ответы [ 4 ]

6 голосов
/ 02 мая 2011

Согласно документации для ssize_t write(int fildes, const void *buf, size_t nbyte)

Если значение nbyte больше, чем {SSIZE_MAX}, результат определяется реализацией.

Таким образом, каждая конкретная реализация может обрабатывать эту ситуацию по-своему. Я не удивлюсь, если некоторые реализации просто установят EFBIG.

Что касается обоснования, возможно, size_t - это просто лучший тип для семантического представления размера буфера? В нем говорится, что этот аргумент имеет неотрицательный размер и ничего более.

5 голосов
/ 02 мая 2011

Я думаю, что это хорошо, так как size_t - это тип значения, возвращаемого оператором sizeof, это разрешает такие вызовы:

char buffer[1 << 20];
ssize_t wrote;

wrote = write(fd, buffer, sizeof buffer);

Если функция взяла подписанную версию, потребуется приведение. Кроме того, как указывали другие, семантические функции, подобные этим , не могут принимать отрицательные значения, поэтому не имеет смысла принимать их.

2 голосов
/ 02 мая 2011

Если параметр не подписан, он устраняет необходимость проверки бессмысленных отрицательных запросов.

1 голос
/ 02 мая 2011

write может записывать только из одного смежного массива unsigned char, который не может быть больше PTRDIFF_MAX, то есть (во всех реальных системах POSIX, и, возможно, это требуется и для POSIX ...?) равно SIZE_MAX/2.Таким образом, передача значения, которое будет отрицательным, если его интерпретировать как значение со знаком, для начала является ошибкой программирования - переданный размер не согласуется с доступным пространством в буфере.

В теории readv и writev может выполнять операции ввода-вывода больше, чем SIZE_MAX/2, повторяя одни и те же буферы iov несколько раз в массиве, но, если я правильно помню, они указывают на сбой, если общий размер будет больше, чем SSIZE_MAX.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...