Использование ssize_t vs int
код
У меня есть функция, которую я могу написать одним из четырех возможных способов:
int do_or_die(int retval);
int do_or_die(ssize_t retval);
ssize_t do_or_die(int t retval);
ssize_t do_or_die(ssize_t retval);
И затем он будет вызываться с обоими способами для библиотечных функций:
written = do_or_die(write(...)); // POSIX write returns ssize_t
printed = do_or_die(printf(...)); // printf returns int
Вопросы
- Какой прототип я должен использовать?
- Какие типы я должен предоставить
written
и printed
?
Я хочу иметь самый надежный и стандартный код, имея при этом только одну функцию do_or_die
.
Я использую C99 в этом случае, но если ответ отличается для C11, то я тоже хотел бы знать это на будущее.
Ответы
Ответ 1
В стандартах C или POSIX нет гарантии, что sizeof(int) >= sizeof(ssize_t)
, а также наоборот. Обычно ssize_t
больше, чем int
, но безопасная и портативная опция на C99 заключается в использовании intmax_t
вместо аргумента и возвращаемого значения.
Единственные гарантии, которые у вас есть. соотношение между int
и ssize_t
:
-
int
может хранить значения, по меньшей мере, диапазона [-2 ^ 15... 2 ^ 15-1] в соответствии с ISO C
-
ssize_t
может хранить значения, по крайней мере, диапазона [-1... 2 ^ 15-1] за POSIX (см. _POSIX_SSIZE_MAX
).
(Интересно, что даже нет гарантии, что ssize_t
может хранить отрицательные копии своего положительного диапазона. Это не подписанный size_t
, а "тип размера" со значением ошибки.)
Ответ 2
Использовать типы способом:
- вы не смешиваете типы
signed
и unsigned
вместе и
- вы не обрезаете значения из более крупных типов, сохраняя их в меньших типах (переполнение/недополнение)
ssize_t
может быть псевдонимом для int
, но он не является стандартным C и может быть специфичным для среды.
Если ваша программа будет работать в определенной среде, проверьте, есть ли sizeof(ssize_t) <= sizeof(int)
и используйте int
. В противном случае используйте другой тип T
, где sizeof(T)
больше или равно, чем sizeof(int)
и sizeof(ssize_t)
.