C: Почему нет size_t ключевого слова C?
sizeof
- ключевое слово C. Он возвращает размер в типе с именем size_t
. Однако size_t
- это не ключевое слово, но оно определяется главным образом в stddef.h
и, возможно, также в других файлах заголовков стандартного C.
Рассмотрим сценарий, в котором вы хотите создать программу на языке C, в которой не не содержится никаких стандартных заголовков или библиотек стандарта C. (Например, если вы создаете ядро ОС.) Теперь в таком коде можно использовать sizeof
(это ключевое слово C, поэтому оно является частью языка), но тип, который он возвращает (size_t
) недоступен!
Разве это не означает какую-либо проблему в стандартной спецификации C? Можете ли вы это уточнить?
Ответы
Ответ 1
Это не буквально возвращает значение типа size_t, так как size_t не является конкретным типом сам по себе, а скорее typedef для неуказанного встроенного типа. Идентификаторы Typedef (такие как size_t) полностью эквивалентны их соответствующим базовым типам (и преобразуются в них во время компиляции). Если size_t определяется как unsigned int на вашей платформе, sizeof возвращает unsigned int, когда он компилируется в вашей системе. size_t - это просто удобный способ поддержания переносимости и должен быть включен только в stddef.h, если вы используете его явно по имени.
Ответ 2
sizeof
- это ключевое слово, потому что, несмотря на его имя и использование, это оператор вроде +
или =
или <
, а не как функция printf()
или atoi()
или fgets()
. Многие люди забывают (или просто не знают), что sizeof
на самом деле является оператором и всегда разрешается во время компиляции, а не во время выполнения.
Для языка C не требуется size_t
для использования, согласованный язык. Это просто часть стандартной библиотеки. Языку C нужны все операторы. Если вместо +
C использовало ключевое слово plus
для добавления чисел, вы сделали бы его оператором.
Кроме того, я делаю полу-неявную переработку size_t
до unsigned int
(и регулярных int
s, но Kernighan и Ritchie когда-нибудь меня порадуют). Вы можете назначить тип возврата sizeof
для int, если хотите, но в моей работе я обычно просто передаю его прямо на malloc()
или что-то в этом роде.
Ответ 3
Некоторые заголовки из стандарта C определены для автономной среды, то есть подходят для использования, например. в ядре операционной системы. Они не определяют никаких функций, просто определяют и typedefs.
Это float.h, iso646.h, limits.h, stdarg.h, stdbool.h, stddef.h и stdint.h.
При работе в операционной системе с этими заголовками начинать не стоит. Имея их в наличии, многое делает проще в вашем ядре. Особенно stdint.h станет удобной (uint32_t и др.).
Ответ 4
Разве это не означает какую-либо проблему в стандартной спецификации C?
Посмотрите разницу между размещенной реализацией C и автономной реализацией C. Для предоставления заголовков требуется автономная (C99) реализация:
-
<float.h>
-
<iso646.h>
-
<limits.h>
-
<stdarg.h>
-
<stdbool.h>
-
<stddef.h>
-
<stdint.h>
Эти заголовки вообще не определяют никаких функций. Они определяют части языка, которые специфичны для конкретного компилятора (например, макрос offsetof
в <stddef.h>
), а макросы и типы списка переменных аргументов в <stdarg.h>
), но их можно обрабатывать, не будучи фактически встроенными в язык как полные ключевые слова.
Это означает, что даже в вашем гипотетическом ядре вы должны ожидать, что компилятор C предоставит эти заголовки и любые основные вспомогательные функции, даже если вы предоставляете все остальное.
Ответ 5
Я думаю, что основными причинами, по которым size_t
не является ключевым словом, являются:
- нет никаких веских оснований для этого. Дизайнеры языков C и С++ всегда предпочитали, чтобы языковые функции были реализованы в библиотеке, если это было возможно и разумно.
- Добавление ключевых слов на язык может создать проблемы для существующего кода устаревшего кода. Это еще одна причина, по которой они обычно устойчивы к добавлению новых ключевых слов.
Например, при обсуждении следующей крупной версии стандарта С++ Stroustrup сказал это:
Улучшения С++ 0x должны быть выполнены таким образом, чтобы результирующий язык был легче изучать и использовать. Среди правил для комитета:
...
- Предпочитают стандартные библиотеки для языковых расширений.
...
Ответ 6
Нет причин не включать stddef.h, даже если вы работаете над ядром - он определяет размеры типов для вашего конкретного компилятора, что любой код будет нужен.
Обратите внимание также, что почти все компиляторы C скомпилированы. Фактический код компилятора для оператора sizeof будет поэтому использовать size_t и ссылаться на тот же файл stddef.h, как и на код пользователя.
Ответ 7
size_t - фактически тип - часто беззнаковый int. Sizeof - это оператор, который задает размер типа. Тип, возвращаемый sizeof, фактически является специфичным для реализации, а не стандартом C. Это просто целое число.
Изменить:
Чтобы быть предельно ясным, вам не нужен тип size_t, чтобы использовать sizeof. Я думаю, что ответ, который вы ищете, - Да, это непоследовательно. Однако это не имеет значения. Вы все равно можете практически правильно использовать sizeof, не имея определения size_t из файла заголовка.
Ответ 8
От MSDN:
При использовании оператора sizeof к объекту типа char он дает 1
Даже если у вас нет stddef.h доступного/включенного и не знаю о size_t, используя sizeof, вы можете получить размер объектов относительно char.
Ответ 9
size_t не является ключевым словом по необходимости. Различные архитектуры часто имеют разные размеры для интегральных типов. Например, у 64-разрядной машины, вероятно, будет unsigned long long как size_t, если они не решили сделать int 64-разрядный тип данных.
Если вы сделаете sizeof встроенного типа компилятору, тогда он уберет возможность выполнить кросс-компиляцию.
Кроме того, sizeof больше похож на волшебный макрос времени компиляции (думаю, С++-шаблон), который объясняет, почему это ключевое слово вместо определенного типа.
Ответ 10
Простая причина в том, что это не фундаментальный тип. Если вы посмотрите на стандарт C, вы обнаружите, что основные типы включают int
, char
и т.д., Но не size_t
. Почему так? Как уже указывали другие, size_t
представляет собой специфичный для реализации тип (т.е. Тип, способный удерживать размер в количестве "байтов C" любого объекта).
С другой стороны, sizeof
является (унарным) оператором. Все операторы - это ключевые слова.