我的问题非常简单:根据cppreference,std::intmax_t
被定义为maximum width integer type
,为什么它与GCC中的__int128_t
不对应?
答案 0 :(得分:13)
我认为这违反了C和C ++标准 - 或者gcc不认为__int128_t
是整数类型。
C标准(1999年和2011年版本)不要求intmax_t
成为标准类型之一;它必须是“能够表示任何有符号整数类型的任何值的有符号整数类型”。特别是,它可以是扩展整数类型 - 如果存在128位扩展整数类型,则intmax_t
必须至少为128位宽。
C标准甚至建议使用实现定义的关键字“具有为任何用途保留的标识符的形式”作为扩展整数类型的名称 - 例如__int128_t
。
2011 C ++标准采用C99的扩展整数类型功能,并遵循1999 C标准定义intmax_t
和<stdint.h>
。
因此,如果__int128_t
是一个整数类型,在标准定义的意义内(它当然可以),并且,顾名思义,128位宽,然后intmax_t
必须至少为128位宽。
作为Stephen Canon's answer,更改intmax_t
确实需要一些工作。 C和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 manual(强调添加):
作为扩展,支持整数标量类型
__int128
具有足够宽的整数模式以保持128位的目标。 只需为签名的128位整数写__int128
,或unsigned __int128
对于无符号的128位整数。 GCC没有支持表达整数 对于具有的目标,__int128
类型的常量long long
小于128位宽的整数。
我想有人可能会争辩说“作为一个扩展”一词让gcc摆脱困境,证明该标准第4节第6段__int128_t
的存在是正确的:
符合要求的实施可能有扩展(包括附加 库函数),只要它们不改变任何行为 严格遵守计划。
而不是根据第6.2.6节第4段:
可能还有实现定义的扩展有符号整数 类型
(我个人认为intmax_t
至少与__int128_t
一样宽,如果存在,则会更符合标准的意图,即使它(几乎没有)可以说它没有违反标准的字母。)
答案 1 :(得分:12)
更改intmax_t
不仅需要更改编译器,还需要更多需要接受intmax_t
参数的标准库函数(平台ABI也可以定义intmax_t
)。编译器可以单方面提供__int128_t
作为扩展,但不能单方面更改类型intmax_t
。这需要编译器所针对的所有标准库实现的支持。
答案 2 :(得分:4)
__ int128功能不足以用作intmax_t
stdint.h标头必须包含一个定义INTMAX_C(9999999999999999999999) 此定义允许您在C源中为任何值输入一个常量,直到该类型的最大大小。
GCC文档说“GCC没有支持为长整数小于128位的目标表达__int128类型的整数常量。”
因此,它不能用于intmax_t。