7

Что говорит стандарт C++ о размерах типов int и long?

7

Я ищу детальную информацию о размерах базовых типов C++. Я понимаю, что это зависит от архитектуры (16 бит, 32 бит, 64 бита) и компилятора.

Но существуют ли какие-либо стандарты для C++?

Я использую Visual Studio 2008 на 32-битной архитектуре. Вот что я получил:

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

Я пытался найти, но не с большим успехом, надежную информацию о размерах char, short, int, long, double, float (и других типах, о которых я не подумал) для различных архитектур и компиляторов.

5 ответ(ов)

2

Для 32-разрядных систем «фактическим» стандартом является ILP32, что означает, что int, long и указатели занимают по 32 бита.

Для 64-разрядных систем основным стандартом Unix является LP64, в котором long и указатели — 64 бита (в то время как int остается 32 битами). Стандарт Windows для 64-разрядных систем — LLP64, где long long и указатели также 64 бита (в то время как long и int остаются 32 битами).

Некоторое время некоторые системы Unix использовали организацию ILP64.

Ни один из этих фактических стандартов не закреплен в стандарте C (ISO/IEC 9899:1999), но все они допускаются.

По умолчанию sizeof(char) равен 1, несмотря на тест в скрипте конфигурации Perl.

Стоит отметить, что были машины (например, Cray), где CHAR_BIT был значительно больше 8. Это означало, что, насколько я помню, sizeof(int) также был равен 1, поскольку как char, так и int были 32-битными.

0

На практике такого понятия как "стандартный размер целого типа" не существует. Обычно можно ожидать, что std::size_t будет представлять собой беззнаковый тип целого числа, соответствующий нативному размеру целого числа на текущей архитектуре, то есть 16 бит, 32 бита или 64 бита, но это не всегда так, как указывают в комментариях к этому ответу.

Что касается всех остальных встроенных типов, то это зависит от компилятора. Вот два выдержки из действующего рабочего проекта последнего стандарта C++:

Есть пять стандартных типов знаковых целых чисел: signed char, short int, int, long int и long long int. В этом списке каждый тип обеспечивает хотя бы такой же объем памяти, как и предшествующие ему типы.

Для каждого из стандартных знаковых целых типов существует соответствующий (но различный) стандартный беззнаковый целый тип: unsigned char, unsigned short int, unsigned int, unsigned long int и unsigned long long int, каждый из которых занимает такое же количество памяти и имеет такие же требования к выравниванию.

Если вы хотите, вы можете статически (время компиляции) проверить sizeof этих фундаментальных типов. Это заставит людей задуматься о переносимости вашего кода, если предположения о размерах изменятся.

0

Обновлено: C++11 официально включил типы из TR1 в стандарт:

  • long long int
  • unsigned long long int

А также "размерные" типы из <cstdint>:

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (и соответствующие беззнаковые).

Дополнительно вы получаете:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • И соответствующие беззнаковые версии.

Эти типы представляют собой минимальные целочисленные типы с как минимум заданным количеством бит. Аналогично существуют "самые быстрые" целочисленные типы с как минимум указанным количеством бит:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • Плюс беззнаковые версии.

Что подразумевается под "быстрым", если вообще что-то, зависит от реализации. Это не обязательно самый быстрый вариант для всех задач.

0

Нет, нет стандарта для размеров типов. Стандарт лишь требует, чтобы выполнялись следующие условия:

sizeof(short int) <= sizeof(int) <= sizeof(long int)

Если вам нужны переменные фиксированного размера, лучше всего использовать макросы, как показано ниже:

#ifdef SYSTEM_X
  #define WORD int
#else
  #define WORD long int
#endif

После этого вы можете использовать WORD для определения своих переменных. Мне не очень нравится такой подход, но это самый портативный способ.

0

В C мы можем создавать собственные синонимы для типов данных с помощью оператора typedef, что позволяет установить свой "стандарт".

Например, на машине, где sizeof(int) == 4, мы можем определить:

typedef int int32;

int32 i;
int32 j;
...

Затем, если мы переносим код на другую машину, где размер long int также равен 4, нам нужно будет всего лишь изменить одно определение типа:

typedef long int int32;

int32 i;
int32 j;
...

Таким образом, мы легко адаптируем код под новые условия, просто изменяя определение типа в одном месте.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь