быть в состоянии держать 65535. Это было впервые указано в C99.
у библиотеку функций, которые будут безопасно конвертировать между различными числовыми типами или умирать, пытаясь. Мое намерение примерно равно частям create-полезным-library и learn-C-edge-case.
мойint
-До-size_t
функция запускает GCC-Wtype-limits
предупреждение, что утверждает, что я не должен проверять, еслиint
больше, чемSIZE_MAX
потому что это никогда не будет правдой. (Еще одна функция, которая преобразуетint
вssize_t
выдает одинаковое предупреждение оSSIZE_MAX
.)
Мой MCVE с дополнительными комментариями и детскими шагами:
#include <stdint.h> /* SIZE_MAX */
#include <stdlib.h> /* exit EXIT_FAILURE size_t */
extern size_t i2st(int value) {
if (value < 0) {
exit(EXIT_FAILURE);
}
// Safe to cast --- not too small.
unsigned int const u_value = (unsigned int) value;
if (u_value > SIZE_MAX) { /* Line 10 */
exit(EXIT_FAILURE);
}
// Safe to cast --- not too big.
return (size_t) u_value;
}
Предупреждения компилятораЯ получаю аналогичные предупреждения от GCC 4.4.5 в Linux 2.6.34:
$ gcc -std=c99 -pedantic -Wall -Wextra -c -o math_utils.o math_utils.c
math_utils.c: In function ‘i2st’:
math_utils.c:10: warning: comparison is always false due to limited range of data type
... а также из GCC 4.8.5 в Linux 3.10.0:
math_utils.c: In function ‘i2st’:
math_utils.c:10:5: warning: comparison is always false due to limited range of data type [-Wtype-limits]
if (u_value > SIZE_MAX) { /* Line 10 */
^
Эти предупреждения не кажутся мне оправданными, по крайней мере, в общем случае. (Я не отрицаю, что сравнение может быть «всегда ложным» для некоторой конкретной комбинации аппаратного обеспечения и компилятора.)
Стандарт ССтандарт C 1999 года не исключаетint
быть больше чемSIZE_MAX
.
Раздел "6.5.3.4sizeof
оператор "не обращаетсяsize_t
вообще, кроме как описать это как<stddef.h>
(и другие заголовки) ".
Раздел «7.17 Общие определения<stddef.h>
"определяетsize_t
как "целочисленный тип без знака результатаsizeof
оператор ". (Спасибо, ребята!)
Раздел «7.18.3 Пределы других целочисленных типов» более полезен - он определяет «пределsize_t
" как:
SIZE_MAX
65535
...смыслSIZE_MAX
может быть какнебольшой как 65535. Anint
(подписанный или неподписанный) может быть намного больше, в зависимости от оборудования и компилятора.
Принятый ответ на "unsigned int
противsize_t
«Кажется, поддерживает мою интерпретацию (выделение добавлено):
size_t
тип может быть больше, чем, равноили меньше чем unsigned int
и ваш компилятор может сделать предположения об этом для оптимизации.
В этом ответе цитируется тот же «Раздел 7.17» стандарта Си, который я уже цитировал.
Другие документыМои поиски обнаружили документ Open Group "Нейтральность размера данных и 64-битная поддержка", которая заявляет в разделе" 64-битные модели данных "(выделение добавлено):
ISO / IEC 9899: 1990, Языки программирования - C (ISO C) оставил определениеshort int
,int
,long int
иpointer
намеренно расплывчатые [...] единственными ограничениями было то, чтоint
s должно быть не меньше чемshort
с иlong
s должно быть не меньше чемint
с иsize_t
должен представлять самый большой неподписанный тип, поддерживаемый реализацией, [...] Отношение между основными типами данных может быть выражено как:
sizeof(char)
<=sizeof(short)
<=sizeof(int)
<=sizeof(long)
= sizeof(size_t)
Если это правда, то тестированиеint
противSIZE_MAX
действительно бесполезно ... но в этой статье не приводятся главы и стихи, поэтому я не могу сказать, как ее авторы пришли к своему заключению. Их собственная "Базовая спецификация версии 7"sys/types.h
документы не обращайтесь к этому так или иначе.
Я это понимаюsize_t
вряд ли будет ужеint
, ностандартная гарантия C это сравнениеsome_unsigned_int > SIZE_MAX
будемвсегда быть ложным? Если так, то где?
Есть два полудубликата этого вопроса, но они оба задают более общие вопросы о том, чтоsize_t
должен представлять и когда он должен / не должен использоваться.
"Что такоеsize_t
в С?«не затрагивает отношения междуsize_t
и другие целочисленные типы. Его принятый ответ - просто цитата из Википедии, которая не предоставляет никакой информации, кроме той, которую я уже нашел.
"Какое правильное определениеsize_t
?"начинает почти дубликат моего вопроса, но затем отклоняется от курса, спрашивая, когдаsize_t
следует использовать и почему это было введено. Он был закрыт как дубликат предыдущего вопроса.