x32 ABI为 x86_64 体系结构生成的代码指定了32 位指针等。它结合了 x86_64 架构(包括 64 位 CPU 寄存器)的优点和 32 位指针的减少开销。
标<stdint.h>
头定义了 typedefs int_fast8_t
、int_fast16_t
、int_fast32_t
和int_fast64_t
(以及相应的无符号类型uint_fast8_t
等),其中每一个是:
在至少具有指定宽度的所有整数类型中,通常使用最快的整数类型
带脚注:
不保证指定的类型在所有用途中都是最快的;如果实现没有明确的理由选择一种类型而不是另一种,它将简单地选择一些满足符号和宽度要求的整数类型。
(引自N1570 C11 草案。)
问题是,无论有没有 x32 ABI,应该如何为 x86_64 架构定义类型[u]int_fast16_t
和类型?[u]int_fast32_t
是否有指定这些类型的 x32 文档?它们是否应该与 32 位 x86 定义(均为 32 位)兼容,或者,由于 x32 可以访问 64 位 CPU 寄存器,它们是否应该在有或没有 x32 ABI 的情况下具有相同的大小?(请注意,无论 x32 ABI 是否在使用中,x86_64 都有 64 位寄存器。)
这是一个测试程序(取决于 gcc 特定的__x86_64__
宏):
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
int main(void) {
#if defined __x86_64__ && SIZE_MAX == 0xFFFFFFFF
puts("This is x86_64 with the x32 ABI");
#elif defined __x86_64__ && SIZE_MAX > 0xFFFFFFFF
puts("This is x86_64 without the x32 ABI");
#else
puts("This is not x86_64");
#endif
printf("uint_fast8_t is %2zu bits\n", CHAR_BIT * sizeof (uint_fast8_t));
printf("uint_fast16_t is %2zu bits\n", CHAR_BIT * sizeof (uint_fast16_t));
printf("uint_fast32_t is %2zu bits\n", CHAR_BIT * sizeof (uint_fast32_t));
printf("uint_fast64_t is %2zu bits\n", CHAR_BIT * sizeof (uint_fast64_t));
}
当我用 编译它时gcc -m64
,输出是:
This is x86_64 without the x32 ABI
uint_fast8_t is 8 bits
uint_fast16_t is 64 bits
uint_fast32_t is 64 bits
uint_fast64_t is 64 bits
当我用 编译它时gcc -mx32
,输出是:
This is x86_64 with the x32 ABI
uint_fast8_t is 8 bits
uint_fast16_t is 32 bits
uint_fast32_t is 32 bits
uint_fast64_t is 64 bits
(除了第一行之外,它与输出匹配gcc -m32
,生成 32 位 x86 代码)。
这是 glibc 中的错误(它定义了<stdint.h>
标头),还是遵循某些 x32 ABI 要求?在x32 ABI 文档或x86_64 ABI 文档中都没有对[u]int_fastN_t
类型的引用,但可能有其他东西指定它。
有人可能会争辩说,fast16 和 fast32 类型应该是带有或带有 x32 的 64 位,因为 64 位寄存器可用;这会比当前的行为更有意义吗?
(我已经对原始问题进行了实质性编辑,该问题仅询问了 x32 ABI。现在问题询问了带有或不带有 x32 的 x86_64。)