从1999版开始,ISO C标准定义了一个标准标头<stdint.h>
,该标头定义了typedefintmax_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位整数类型,但是它们不被视为扩展整数类型,并且两个编译器的文档都声明它们不支持任何扩展整数类型。因为这些不是标准定义术语所定义的整数类型,所以typedefintmax_t
和uintmax_t
用于64位类型,而不是128位类型。
这些都没有违反C标准(实现不必具有任何扩展的整数类型,并且只要不破坏任何严格符合标准的程序,它们就可以具有任意扩展名)。但是在我看来,对于__int128
并将unsigned __int128
其视为扩展整数类型以及对于intmax_t
并将uintmax_t
其视为128位类型,这是完全有意义的。
为理由不这样做,是改变的大小intmax_t
和uintmax_t
将是“一个ABI不兼容的变化”。
该锵C ++状态页说,在脚注(5):
对于不提供任何扩展整数类型的实现(例如Clang),不需要更改编译器。
__int128
不将其视为扩展的整数类型,因为更改intmax_t
将是与ABI不兼容的更改。
(是的,主要讨论C ++,但是规则与C相同。)
在gcc错误报告中,声称:
sizeof(intmax_t)
由各种LP64 ABI固定,无法更改
在这两种情况下,都没有给出该权利要求的参考。
一个x86_64的ABI文件名为“System V应用程序二进制接口,AMD64架构处理器补充,草案版本0.99.6”并没有提及intmax_t
或者uintmax_t
,甚至<stdint.h>
头。它确实为预定义的整数类型指定了大小和对齐方式(在图3.1中)。
最后,我的问题是:ABI的大小intmax_t
并uintmax_t
受其限制的说法是否有效?如果是这样,那么ABI会施加什么要求?(顺便说一句,为什么?)
(在我看来,这样的规定,如果存在的话,是不明智的。它击败了C标准的定义扩展整型许可的目的,和预期的意义intmax_t
和uintmax_t
,这使得它更难于使用128位整数在支持它们的系统上有效地输入类型,而回退到其他系统上的窄类型。)
更新:Jens Gustedt在标题为“ intmax t,一种出路”的N2303中建议调整的定义,[u]intmax_t
以允许添加扩展的整数类型,long long
而不必更新[u]intmax_t
。例如,intmax_t
可能是一个typedef long long
,但实现仍然可以提供,说,__int128
作为一个扩展整型。
参考文献:
正如第三十二上校所指出的,编译器单方面进行此更改将中断传递uintmax_t
参数或返回uintmax_t
值的编译单元之间的调用。尽管SysV ABI没有定义如何传递这些类型,但实际上,保持其定义是符合平台ABI的一部分。
即使不是针对此ABI问题,编译器仍然无法单方面进行此更改,因为它需要将更改与每个目标平台的C标准库进行匹配。具体地讲,它至少需要更新的printf
和scanf
函数族,imaxabs
,imaxdiv
,和strtoimax
和strtoumax
及其变体。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句