Почему uintptr_t и intptr_t являются необязательными типами в стандарте C (и C )?

#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. Это также было бы справедливо для реализации с ограниченными указателями или где указатели представляют собой своего рода кортеж идентификатора объекта, смещения и, возможно, другой информации, обеспечивающей реализацию с сохранением памяти.