В x86/amd64 мир sizeof(long long)
равен 8.
Позвольте мне процитировать довольно проницательную 8-летнюю почту Зака Вайнберга:
Скотт Роберт Лэдд пишет:
В 64-битной архитектуре AMD64 GCC определяет
long long
как 64 бита, то же, что иlong
.Учитывая, что некоторые 64-разрядные команды (умножьте) производят 128-битные результаты, разве это не логично, что
long long
определяется как 128 бит?Нет, по двум причинам:
Выбор 64-битного '
long long
' был записан в ABI большинство LP64-моделей; мы не можем в одностороннем порядке изменить его.Это действительно правильный выбор, поскольку он устраняет аберрацию что делает "
long
" не самым широким базовым интегральным типом. Там есть много-много кода в дикой природе, написанное в предположении, чтоsizeof(long) >= sizeof(size_t)
- это, по крайней мере, потенциально сломанный ABI, где длинный длинный длиннее.(Это была чрезвычайно спорная тема в ходе разработки C99. Насколько я могу судить по внешнему виду, '
long long
' был стандартизирован только из-за давления со стороны Microsoft, который не может по какой-то причине реализована модель LP64. Все остальные ненавидели идею сделать 'long
' не обязательно самым широким базовым интегральным типом.)Лучшая современная практика заключается в предоставлении "расширенного интеграла type"
__int128
. Это не проблема "long long
", потому что это не основной интегральный тип (в частности, его нельзя использовать дляsize_t
).ZW
long long
является самым широким базовым интегральным типом. Это 64-битная длина на любых не-мертвых старых архитектурах /ABI, которые я знаю. Это позволяет перейти с простой кросс-платформенной (ну, по крайней мере, для многих 32/64-разрядных архитектур) typedefs:
typedef char s8;
typedef unsigned char u8;
typedef short s16;
typedef unsigned short u16;
typedef int s32;
typedef unsigned int u32;
typedef long long s64;
typedef unsigned long long u64;
которые лучше, чем intXX_t
, потому что:
- они используют один и тот же базовый тип для 64-битных целых чисел на разных платформах.
- позволяет избежать подробных
PRId64
/PRIu64
(Мне хорошо известно, что Visual С++ поддерживает%lld
/%llu
только с 2005 года)
Но как переносимое это решение может быть выражено ответами на следующий вопрос.
Каковы архитектуры /ABI, где sizeof(long long) != 8
?
Если вы не можете предоставить какие-либо последние/современные, перейдите к старым, но только если они все еще используются.