#c #language-lawyer
#c #c #c 11 #c99
Вопрос:
С C99 (и более поздними стандартами) стандарт требует, чтобы определенные типы были доступны в заголовке <stdint.h>
. Для точной ширины, например, int8_t
, int16_t
и т. Д., Они необязательны и мотивированы в стандарте, почему это так.
Но для типа uintptr_t
и intptr_t
они также необязательны, но я не вижу причины, по которой они являются необязательными, а не обязательными.
Комментарии:
1. Может существовать оборудование, которое не может их поддерживать (эффективно). Таким образом, стандарт не может предписывать их. Для обычных платформ вы можете в значительной степени предположить, что они существуют — вы бы знали, если бы их не было на выбранной вами платформе.
2. @JesperJuhl: На мой взгляд, это сомнительное дизайнерское решение. Даже если
uintptr_t
это было бы неэффективно, его наличие — лучшее решение, чем его отсутствие. Существуют проблемы, которые могут быть решены только с помощью этого типа (способом, определяемым реализацией). Таким образом, качественная реализация всегда должна предоставлять этот тип.3. @geza Нет особого смысла в том, чтобы иметь переносимый тип, который используется способом, определяемым реализацией , если подумать об этом…
4. @ArneVogel: это кажется противоречием, но это не так. Если
uintptr_t
всегда доступно, то программы, которые его используют, могут быть более переносимыми, поскольку вам не нужно беспокоиться о том, доступно оно или нет. Есть проблемы, когда точное преобразование не имеет значения. Например, связанный список xor. И я думаю, что качественная реализация должна выполнять ожидаемые действия: например, добавление 1 кTYPE *
должно выполнять то же самое, что и добавлениеsizeof(TYPE)
к преобразованному целому числу (таким образом, неопределенное поведение expr.add можно обойти).
Ответ №1:
На некоторых платформах типы указателей имеют гораздо больший размер, чем любой интегральный тип. Я полагаю, что примером такой платформы может быть IBM AS / 400 с набором виртуальных команд, определяющим все указатели как 128-битные. Более свежим примером такой платформы может быть Elbrus. Он использует 128-битные указатели, которые являются дескрипторами HW, а не обычными адресами.
Комментарии:
1. Есть ли какие-либо примеры таких платформ?
2. @BoR Конечно, как насчет реального режима x86, где адреса имеют длину 20 бит, но размер машинного слова равен 16 битам?
3. @Oliv: Должно быть гораздо больше. 2 ^ 128 равно ~ 10 ^ 38. Масса Земли составляет ~ 6 * 10 ^ 24 кг. Если мы используем с очень тяжелыми атомами, для которых моль равна 1 кг, то Земля имеет 6*10^24*6*10^23 = 3.6*10^48 атомы. По крайней мере, поскольку это очень пессимистичная оценка. Это намного выше, чем 2 ^ 128. 🙂
4. во вселенной около 10 ^ 80 предполагаемых атомов, и это в 3 * 10 ^ 41 раз больше, чем 2 ^ 128 🙂
5. Это также было бы справедливо для реализации с ограниченными указателями или где указатели представляют собой своего рода кортеж идентификатора объекта, смещения и, возможно, другой информации, обеспечивающей реализацию с сохранением памяти.