为什么在g ++中std :: intmax_t不是__int128_t?

时间:2014-01-21 17:47:07

标签: c++ c gcc integer standards

我的问题非常简单:根据cppreferencestd::intmax_t被定义为maximum width integer type,为什么它与GCC中的__int128_t不对应?

3 个答案:

答案 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。