x32 ABI указывает, среди прочего, 32-разрядные указатели для кода, сгенерированного для архитектуры x86_64. Он сочетает в себе преимущества архитектуры x86_64 (включая 64-разрядные регистры процессора) с уменьшенными накладными расходами 32-разрядных указателей.Как должны быть определены типы [u] int_fastN_t для x86_64 с или без x32 ABI?
Заголовок <stdint.h>
определяет определений типов int_fast8_t
, int_fast16_t
, int_fast32_t
и int_fast64_t
(и соответствующих беззнаковых типов и др), каждая из которых является:
целочисленный тип, который, как правило, быстро оперировать среди всех целые типы, которые имеют по меньшей мере заданную ширину
со сноской:
Назначенный тип не гарантируется как самый быстрый для всех целей; , если в реализации нет четких оснований для выбора одного типа по сравнению с другим, он просто выберет целочисленный тип, удовлетворяющий требованиям подписи и ширины .
(Цитируется N1570 C11 draft.)
Вопрос заключается в том, каким образом следует [u]int_fast16_t
и [u]int_fast32_t
типы определены для архитектуры x86_64, с или без x32 ABI? Есть ли документ x32, который указывает эти типы? Должны ли они быть совместимы с 32-разрядными определениями x86 (оба 32 бита) или, поскольку x32 имеет доступ к 64-разрядным регистрам CPU, должны ли они быть того же размера с или без 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 document или x86_64 ABI document, но может быть что-то другое, что его определяет.
Можно утверждать, что типы fast16 и fast32 должны быть 64 бит с или с x32, поскольку доступны 64-разрядные регистры; было бы более разумно, что нынешнее поведение?
(Я существенно отредактировал исходный вопрос, который задал вопрос только о x32 ABI. Теперь задается вопрос о x86_64 с или без x32.)
Зачем это ошибка в glibc? –
@ RossRidge: Если ваша точка в том, что '' предоставляется glibc, а не gcc, вы правы; Я обновил вопрос. Если вы говорите, что это не ошибка, меня бы заинтересовало ваше обоснование. Поскольку система имеет 64-разрядные регистры, 'int64_t' должен быть быстрее, чем' int32_t', поэтому 'int_fast32_t' должно быть 64 бита, как и в x86_64. –
Мне интересно сначала услышать ваше разумное. Почему бы 64-разрядные регистры делать 'int64_t' быстрее, чем' int32_t' при работе со значениями, которым требуется только 32 бита? –