Ответ 1
Я считаю, что это нарушение стандартов C и С++ - либо это, либо gcc не считает, что __int128_t
является целым типом.
Стандарт C (как выпуски 1999 г., так и 2011 г.) не требует, чтобы intmax_t
был одним из стандартных типов; он должен быть "объявленным целочисленным типом, способным представлять любое значение любого целочисленного типа со знаком". В частности, это может быть расширенный целочисленный тип - и если существует 128-разрядный расширенный целочисленный тип, то intmax_t
должен иметь ширину не менее 128 бит.
Стандарт C даже предполагает использование ключевых слов, определенных для реализации, которые "имеют форму идентификатора, зарезервированного для любого использования" в качестве имен расширенных целых типов, например __int128_t
.
В стандарте С++ 2011 используется функция расширенных целочисленных типов C99 и отсылается к стандарту 1999 C для определения intmax_t
и <stdint.h>
.
Итак, если __int128_t
является целым типом в значении, определенном стандартом (что, безусловно, может быть), и, как следует из названия, имеет ширину 128 бит, тогда intmax_t
должно быть не менее 128 бит.
Как Ответ Стивена Canon, изменение intmax_t
требует некоторой работы. Стандарты C и С++ не признают это как оправдание неправильного определения intmax_t
.
Конечно, все это в равной степени относится к uintmax_t
.
#include <stdio.h>
#include <stdint.h>
int main(void) {
__uint128_t huge = UINTMAX_MAX;
huge ++;
if (huge > UINTMAX_MAX) {
puts("This should not happen");
}
}
В моей системе (Linux x86_64, gcc 4.7.2) вышеуказанная программа печатает:
This should not happen
Если gcc соответствует стандарту, то это должно быть возможно только в том случае, если __int128_t
не является целым типом, но цитирует gcc 4.8.2 руководство (выделено мной):
В качестве расширения поддерживается целочисленный скалярный тип
__int128
для цели, которые имеют целочисленный режим, достаточно широкий для хранения 128 бит. Просто напишите__int128
для подписанного 128-битного целого числа илиunsigned __int128
для неподписанного 128-битного целого. В GCC нет поддержки для выражения целого числа константа типа__int128
для целей сlong long
целое число менее 128 бит.
Я полагаю, можно утверждать, что фраза "как расширение" позволяет gcc отключиться отсюда, оправдывая существование __int128_t
в соответствии с пунктом 6 раздела 4 стандарта:
Соответствующая реализация может иметь расширения (включая дополнительные библиотечные функции) при условии, что они не изменяют поведение каких-либо строго соответствующая программа.
а не в соответствии с разделом 6.2.6, пункт 4:
Также может быть реализовано расширенное целое число с расширенной поддержкой реализации типы.
(Я лично считаю, что создание intmax_t
, по крайней мере, столь же широкого, как __int128_t
, если оно существует, будет больше соответствовать намерению стандарта, даже если он (едва ли) может утверждать, что он не " t нарушает букву стандарта.)