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

Vin*_*ent 12 c c++ standards gcc integer

我的问题非常简单:根据cppreference的std::intmax_t定义,为什么它与GCC 不对应?maximum width integer type__int128_t

Kei*_*son 14

我认为这违反了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的回答,改变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");
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的系统(Linux x86_64,gcc 4.7.2)上,上面的程序打印:

This should not happen
Run Code Online (Sandbox Code Playgroud)

如果gcc符合标准,那么只有当__int128_t它不是整数类型时才应该可行- 但是引用gcc 4.8.2手册(强调添加):

作为扩展,整数标量类型 __int128支持具有足够容纳128位的整数模式的目标.只需写入__int128带符号的128位整数,或写入unsigned __int128 无符号的128位整数.GCC中不支持为整数小于128位的__int128目标 表示类型的整数常量long long.

我想有人可能会争辩说"作为一个扩展"一词让gcc摆脱困境,证明__int128_t了标准第4节第6段的存在:

符合实现的实现可能具有扩展(包括附加库函数),前提是它们不会改变任何严格符合程序的行为.

而不是根据第6.2.6节第4段:

也可能存在实现定义的扩展有符号整数类型.

(我个人认为,intmax_t至少尽可能宽__int128_t,如果它存在,将更符合标准的意图,即使它(几乎不可能)认为它不违反标准的字母.)

  • 一位特别坚定的语言律师可能会争辩说,"扩展整数类型"的概念从未被标准正式定义; 只要GCC没有说`__int128_t`就是这样的类型,并且只要他们不将文字解释为具有该类型,就没有标准违规.一个更合理的实用主义者可能会争辩说编译器应该警告你正在使用扩展,但是支持该类型,因为它真的很有用. (2认同)
  • @StephenCanon:因此需要注意:"或者,或者gcc不认为`__int128_t`是一个整数类型".尽管如此,我认为将`intmax_t`作为`__int128_t`的typedef会更多地符合标准的精神(以及字母)而不是使`intmax_t`小于`__int128_t`. (2认同)

Ste*_*non 12

更改intmax_t不仅需要更改编译器,还需要更多需要接受intmax_t参数的标准库函数(平台ABI也可以定义intmax_t).编译器可以单方面提供__int128_t扩展,但不能单方面改变类型intmax_t.这需要编译器所针对的所有标准库实现的支持.

  • 另外,预处理阶段也必须考虑到这一点.它应该解码该类型的常量,并在`[u] intmax_t`中计算其所有表达式. (2认同)

use*_*044 5

__int128 的功能不足以用作 intmax_t

stdint.h 头文件必须包含一个定义 INTMAX_C(9999999999999999999999) 这个定义允许你将一个常量输入到 C 源代码中,用于任何值直到类型的最大大小。

GCC 文档说“GCC 不支持为具有小于 128 位宽的 long long 整数的目标表达 __int128 类型的整数常量。”

因此,它不能用于 intmax_t。

  • 常量表达式必须适用于 `#if` 表达式,因此不允许强制转换。此外,这种技术对 `INTMAX_C` 没有帮助,它需要能够处理程序员可能希望使用的任何整数(在范围内)。 (2认同)