Подтвердить что ты не робот

Архитектура/ABI, где sizeof (long long)!= 8

В 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?

Если вы не можете предоставить какие-либо последние/современные, перейдите к старым, но только если они все еще используются.

4b9b3361

Ответ 1

Архитектура TI TMS320C55x имеет CHAR_BIT 16-битных и long long 40-битных. Хотя 40-бит long long нарушает ISO, sizeof (long long) отличается от 8.

На самом деле почти все реализации C99 с CHAR_BIT > 8 имеют sizeof (long long) != 8.

TMS320C55x Оптимизация Руководство пользователя компилятора C/С++ (2003) http://www.ti.com/lit/ug/spru281f/spru281f.pdf

Ответ 2

Ваши "кросс-платформенные" typedefs просто ошибочны. Правильными являются

#include <stdint.h>
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
...