Начиная с выпуска 1999 года, стандарт ISO C определяет стандартный заголовок <stdint.h>
, который, среди прочего, определяет typedefs intmax_t
и uintmax_t
. Они обозначают, соответственно, "целочисленный тип (подписанный | без знака), способный представлять любое значение любого (подписанного | беззнакового) целочисленного типа".
Например, если, как это обычно бывает, самые широкие целочисленные типы с подписью и без знака являются long long int
и unsigned long long int
, оба из которых обычно являются 64 битами, тогда intmax_t
и uintmax_t
могут быть определены в <stdint.h>
следующим образом:
typedef long long int intmax_t;
typedef unsigned long long int uintmax_t;
Существует ограниченный набор предопределенных стандартных и беззнаковых целочисленных типов, начиная от signed
, unsigned
и обычного char
до signed
и unsigned
long long int
.
C99 и C11 также позволяют реализациям определять расширенные целочисленные типы, которые отличаются от любого из стандартных типов и имеют имена, которые являются ключевыми словами, определяемыми реализацией.
Оба gcc и clang, для некоторых, но не для всех целей, поддерживают типы __int128
и unsigned __int128
. Они действуют как 128-битные целочисленные типы, но они не рассматриваются как расширенные целочисленные типы, а документация для обоих компиляторов заявляет, что они не поддерживают расширенные целые типы. Поскольку они не являются целыми типами, поскольку стандарт определяет этот термин, typedefs intmax_t
и uintmax_t
относятся к 64-разрядным типам, а не к 128-битным типам.
Ничто из этого не нарушает стандарт C (для реализации не требуются какие-либо расширенные целочисленные типы, и им разрешено иметь произвольные расширения, если они не нарушают каких-либо строго соответствующих программ). Но мне кажется, что для __int128
и unsigned __int128
было бы разумным рассматривать как расширенные целые типы, а для intmax_t
и uintmax_t
- 128-битные типы.
Обоснование этого не означает, что изменение размера intmax_t
и uintmax_t
будет "несовместимым с ABI изменением".
страница статуса Clang С++ в сноске (5):
Никаких изменений компилятора не требуется для реализации, такой как Clang, которая не предоставляет никаких расширенных целочисленных типов.
__int128
не рассматривается как расширенный целочисленный тип, поскольку изменениеintmax_t
будет несовместимым с ABI изменением.
(Да, это в первую очередь обсуждает С++, но правила те же, что и для C.)
В отчете gcc bug утверждается, что:
sizeof(intmax_t)
фиксируется различными LPI AB64 и не может быть изменен
В обоих случаях для этой заявки не приводится никаких ссылок.
x86_64 ABI document под названием "Бинарный интерфейс приложения System V, приложение для архитектуры архитектуры AMD64, черновик версии 0.99.6" не упоминает intmax_t
или uintmax_t
, или даже заголовок <stdint.h>
. Он задает размеры и выравнивания для предопределенных целых типов (на рис. 3.1).
Наконец, мой вопрос: является ли утверждение, что размеры intmax_t
и uintmax_t
ограничены ABI действительными? Если да, то какое ABI налагает такое требование? (И, кстати, почему?)
(На мой взгляд, такое требование, если оно существует, неразумно. Оно побеждает цель стандартного разрешения C для определения расширенных целочисленных типов и предполагаемого значения intmax_t
и uintmax_t
. гораздо сложнее использовать 128-битные целочисленные типы эффективно для систем, которые их поддерживают, а также возвращаются к более узким типам в других системах.)
Литература:
- N1256, черновик стандарта C99
- N1570, проект стандарта C11
- System V AMD64 ABI