C:почему размер T не является ключевым словом C?

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

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

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

10 ответов


Он буквально не возвращает значение типа size_t, так как size_t не является конкретным типом сам по себе, а скорее typedef для неопределенного встроенного типа. Идентификаторы Typedef (такие как size_t) полностью эквивалентны их соответствующим базовым типам (и преобразуются в них во время компиляции). Если size_t определяется как unsigned int на вашей платформе, то sizeof возвращает unsigned int при компиляции в вашей системе. size_t-это просто удобный способ поддерживать мобильность и только нужно быть включенным в stddef.h если вы используете его явно по имени.


sizeof является ключевым словом, потому что, несмотря на его имя и использование, это оператор как + или = или <, а не функции как printf() или atoi() или fgets(). Многие забывают (или просто не знают), что sizeof фактически является оператором, и составляет всегда разрешена во время компиляции, а не во время выполнения.

язык C не нуждается size_t быть годным к употреблению, последовательным языком. Это только часть стандартной библиотеки. Язык C нуждается во всех операторах. Если вместо +, C использовал ключевое слово plus чтобы добавить числа, вы бы сделали его оператором.

кроме того, я делаю полу-неявная переплавка size_ts до unsigned ints (и регулярные ints, но Керниган и Ричи когда-нибудь будут бить меня за это) все время. Вы можете назначить возвращаемый тип a sizeof в int, если хотите, но в моей работе я обычно просто передаю его прямо на malloc() или что-то.


некоторые заголовки из стандарта C определены для freestanding среда, т. е. пригодная для использования, например, в ядре операционной системы. Они не определяют каких-либо функций, а просто определяют и typedefs.

Они плавают.h, iso646.ч, пределы.ч, включаемом файле stdarg.h, stdbool.h, stddef.h и stdint.h.

при работе с операционной системой неплохо начать с эти заголовки. Наличие их делает многие вещи проще в вашем ядро. Особенно stdint.h станет удобным (uint32_t и др.).


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

найдите разницу между размещенной реализацией C и автономной реализацией C. Для обеспечения заголовков требуется автономная реализация (C99) :

  • <float.h>
  • <iso646.h>
  • <limits.h>
  • <stdarg.h>
  • <stdbool.h>
  • <stddef.h>
  • <stdint.h>

эти заголовки не определяют никаких функций вообще. Они определяют части языка, которые несколько специфичны для компилятора (например,offsetof макрос <stddef.h>, а список переменных аргументов макросов и типов в <stdarg.h>), но их можно обрабатывать без фактического будучи встроенным в язык в качестве полных ключевых слов.

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


Я думаю, что основные причины этого size_t не является ключевым словом:

  • для этого нет веских причин. Разработчики языков C и c++ всегда предпочитали, чтобы языковые функции были реализованы в библиотеке, если это возможно и разумно
  • добавление ключевых слов в язык может создать проблемы для существующего массива устаревшего кода. Это еще одна причина, по которой они обычно устойчивы к добавлению новых ключевое слово.

например, при обсуждении следующего крупного пересмотра стандарта C++,Страуструп сказал:

улучшения C++0x должны быть сделаны таким образом, чтобы результирующий язык был легче изучать и использовать. Среди эмпирических правил для комитета:

...

  • предпочитайте стандартные средства библиотеки языковым расширениям

...


нет причин не включать stddef.h, даже если вы работаете над ядром-он определяет размеры типов для вашего конкретного компилятора, который понадобится любому коду.

Отметим также, что почти все компиляторы с собственной компиляции. Поэтому фактический код компилятора для оператора sizeof будет использовать size_t и ссылаться на тот же stddef.H-файл, как код пользователя.


с MSDN:

при применении оператора sizeof для объекта типа char он дает 1

даже если у вас нет stddef.h доступно / включено и не знает о size_t, используя sizeof вы можете получить размер объектов относительно char.


size_t на самом деле тип - часто unsigned int. Sizeof-это оператор, который дает размер типа. Тип, возвращаемый sizeof, на самом деле зависит от реализации, а не от стандарта C. Это просто целое число.

изменить: Чтобы быть очень ясным, вам не нужен тип size_t для использования sizeof. Я думаю, что ответ, который вы ищете, - Да, он непоследователен. Однако,это не важно. вы все еще можете практически использовать sizeof правильно, не имея size_t определение из заголовочного файла.


реализация не является ключевым словом по необходимости. Различные архитектуры часто имеют разные размеры для интегральных типов. Например, 64-разрядная машина может иметь unsigned long long as реализация если они не решили сделать int 64-битный тип данных.

Если вы сделаете sizeof встроенным типом компилятора, то это отнимет власть делать перекрестную компиляцию.

и sizeof более как магический макрос времени компиляции (думаю, шаблон C++), который объясняет, почему это ключевое слово вместо определенного типа.


простая причина в том, что это не фундаментальный тип. Если вы посмотрите на стандарт C, вы обнаружите, что фундаментальные типы включают int, char etc но не size_t. Почему? Как уже указывали другие,size_t - это конкретный тип реализации (т. е. тип, способный удерживать размер в количестве "c байтов" любого объекта).

С другой стороны, sizeof это (унарный) оператор. Все операторы являются ключевыми словами.