Подтвердить что ты не робот

C: Почему нет size_t ключевого слова C?

sizeof - ключевое слово C. Он возвращает размер в типе с именем size_t. Однако size_t - это не ключевое слово, но оно определяется главным образом в stddef.h и, возможно, также в других файлах заголовков стандартного C.

Рассмотрим сценарий, в котором вы хотите создать программу на языке C, в которой не не содержится никаких стандартных заголовков или библиотек стандарта C. (Например, если вы создаете ядро ​​ОС.) Теперь в таком коде можно использовать sizeof (это ключевое слово C, поэтому оно является частью языка), но тип, который он возвращает (size_t) недоступен!

Разве это не означает какую-либо проблему в стандартной спецификации C? Можете ли вы это уточнить?

4b9b3361

Ответ 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 является (унарным) оператором. Все операторы - это ключевые слова.