x32 ABI определяет, среди прочего, 32-разрядные указатели для кода, созданного для архитектуры x86_64. . Он сочетает в себе преимущества архитектуры x86_64 (включая 64-битные регистры ЦП) с уменьшенными накладными расходами 32-битных указателей.
Заголовок <stdint.h>
определяет определения типов int_fast8_t
, int_fast16_t
, int_fast32_t
и int_fast64_t
(и соответствующие типы без знака uint_fast8_t
и др.), Каждый из которых:
целочисленный тип, с которым обычно работать быстрее всего среди всех целочисленных типов, которые имеют как минимум заданную ширину
со сноской:
Не гарантируется, что указанный тип будет самым быстрым для всех целей; если у реализации нет явных оснований для выбора одного типа над другим, она просто выберет некоторый целочисленный тип, удовлетворяющий требованиям подписи и ширины.
(Цитата из N1570 C11 draft.)
Вопрос в том, как следует определять типы [u]int_fast16_t
и [u]int_fast32_t
для архитектуры x86_64, с ABI x32 или без него? Есть ли документ x32, в котором указаны эти типы? Должны ли они быть совместимы с 32-битными определениями x86 (оба 32-битные) или, поскольку x32 имеет доступ к 64-битным регистрам ЦП, должны ли они быть одинакового размера с x32 ABI или без него? (Обратите внимание, что x86_64 имеет 64-разрядные регистры независимо от того, используется ли x32 ABI или нет.)
Вот тестовая программа (которая зависит от специфичного для 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? Ссылки на типы [u]int_fastN_t
отсутствуют в x32 ABI документ или x86_64 ABI-документ, но может быть что-то еще что определяет это.
Можно утверждать, что типы fast16 и fast32 должны быть 64-битными с x32 или с x32, поскольку доступны 64-битные регистры; будет ли это иметь больше смысла, чем нынешнее поведение?
(Я существенно отредактировал исходный вопрос, который касался только x32 ABI. Теперь вопрос касается x86_64 с x32 или без него.)
<stdint.h>
предоставляется glibc, а не gcc, вы правы; Я обновил вопрос. Если вы говорите, что это не ошибка, мне было бы интересно ваше объяснение. Поскольку в системе 64-битные регистры,int64_t
должен быть быстрее, чемint32_t
, поэтомуint_fast32_t
должен быть 64-битным, как и в x86_64. - person Keith Thompson   schedule 01.05.2016int64_t
быстрее, чемint32_t
при работе со значениями, которым требуется только 32 бита? - person Ross Ridge   schedule 01.05.2016[u]int_fast16_t
и[u]int_fast32_t
64-битными. Какое бы ни было обоснование этого решения, оно также применимо к x32, если я чего-то не упускаю. - person Keith Thompson   schedule 01.05.2016[u]int32_t
32 бита на x86_64? В настоящее время они имеют разные размеры на x32 и x86_64; есть ли веские причины отличаться от них? - person Keith Thompson   schedule 01.05.2016int_fast16_t
с 64-битными уже не так привлекательно. - person rodrigo   schedule 01.05.2016int
в большинстве реализаций) выравниваются по 4 байтам, а не по 8. - person Keith Thompson   schedule 01.05.2016