Можно ли предположить, что размер long int всегда равен 4 байтам?

Всегда ли верно, что long int (что, насколько я понимаю, является синонимом для long), это 4 bytes?

Могу ли я полагаться на это? Если нет, это может быть справедливо для ОС на базе POSIX?

Ответ 1

Стандарты ничего не говорят о точном размере любых целых типов, кроме char. Как правило, long является 32-разрядным в 32-битных системах и 64-разрядным в 64-разрядных системах.

Однако стандарт определяет минимальный размер. Из раздела 5.2.4.2.1 Стандарт C:

1 Значения, приведенные ниже, должны быть заменены постоянными выражениями подходит для использования в директивах по препроцессинга #if. Более того, кроме CHAR_BIT и MB_LEN_MAX, должно быть заменяются выражениями, которые имеют тот же тип, что и выражение, являющееся объектом соответствующего типа, преобразованного в соответствии с целыми рекламными акциями. Их реализация определена значения должны быть равны или больше по величине (по абсолютной величине) до те, которые показаны, с тем же знаком.

...

  • минимальное значение для объекта типа long int

    LONG_MIN -2147483647//- (2 ^ 31-1)

  • максимальное значение для объекта типа long int

    LONG_MAX +2147483647//2 ^ 31-1

Это говорит о том, что a long int должно быть как минимум 32 бита, но может быть больше. На машине, где CHAR_BIT равно 8, это дает минимальный размер байта 4. Однако на машине, например. CHAR_BIT, равное 16, a long int может иметь длину 2 байта.

Вот пример реального мира. Для следующего кода:

#include <stdio.h>

int main ()
{
    printf("sizeof(long) = %zu\n", sizeof(long));
    return 0;
}

Вывод на Debian 7 i686:

sizeof (long) = 4

Вывод на CentOS 7 x64:

sizeof (long) = 8

Нет, вы не можете делать какие-либо предположения о размере. Если вам нужен тип определенного размера, вы можете использовать типы, определенные в stdint.h. Он определяет следующие типы:

  • int8_t: подписанный 8-разрядный
  • uint8_t: unsigned 8-bit
  • int16_t: подписанный 16-разрядный
  • uint16_t: unsigned 16-bit
  • int32_t: подписанный 32-разрядный
  • uint32_t: unsigned 32-bit
  • int64_t: подписанный 64-разрядный
  • uint64_t: неподписанный 64-разрядный

Заголовок stdint.h описан в разделе 7.20 стандарта с точными типами ширины в разделе 7.20.1.1. В стандарте указано, что эти typedef являются необязательными, но они существуют в большинстве реализаций.

Ответ 3

Используйте код sizeof(long int) и проверьте размер. Он даст вам размер long int в байтах в системе, в которой вы сейчас работаете. Ответ на ваш вопрос в частности - НЕТ. Это нигде не гарантируется в C или POSIX или где-либо еще.

Ответ 4

Как указано @delnan, реализации POSIX сохраняют размер long и int как неопределенный и часто различаются между 32-битными и 64-битными системами.

Длина long в основном связана с аппаратным (часто совпадающим с размером регистров данных на процессоре, а иногда и с другими проблемами, связанными с программным обеспечением, такими как дизайн ОС и интерфейс ABI).

Чтобы облегчить ваш разум, sizeof не является функцией, а директивой компилятора *, поэтому ваш код не использует операции при использовании sizeof - он то же самое, что и запись номера, только он переносимый.

использование:

sizeof(long int)

* Как отметил Дэйв в комментариях, sizeof будет вычисляться во время выполнения, когда невозможно вычислить значение во время компиляции, например, при использовании массивов переменной длины.

Кроме того, как указано в другом комментарии, sizeof учитывает заполнение и выравнивание, используемые реализацией, что означает, что фактические используемые байты могут отличаться от размера в памяти (это может быть важно при смещении бит).

Если вы ищете конкретные переменные размера байта, подумайте об использовании байтового массива или (я бы предположил, что поддерживаю) типы, определенные C99 в stdint.h - как предложено @dbush.

Ответ 5

Когда мы впервые внедрили C на аппаратном обеспечении ICL Series 39, мы взяли стандарт в своем слове и сопоставили типы данных с естественным представлением на этой машинной архитектуре, которая была short= 32 бит, int= 64 бит, long= 128 бит.

Но мы обнаружили, что никаких серьезных приложений С не работало; все они принимали отображение short= 16, int= 32, long= 64, и нам пришлось сменить компилятор, чтобы поддержать это.

Таким образом, независимо от официального стандарта, в течение многих лет все сходились на long= 64 бит, и это вряд ли изменится.

Ответ 6

стандарт ничего не говорит о размере long int, поэтому он зависит от среды, которую вы используете.

Чтобы получить размер long int в вашей среде, вы можете использовать оператор sizeof и получить размер long int. Что-то вроде

sizeof(long int)
Стандарт

C требует только следующих точек о размерах типов

  • int >= 16 бит,
  • long >= 32 бит,
  • long long (начиная с C99) >= 64 бит
  • sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long) <= sizeof (long long)
  • sizeof (char) == 1
  • CHAR_BIT >= 8

Оставшиеся реализации определены, поэтому он не удивлен, если один столкнулся с некоторыми системами, где int имеет 18/24/36/60 бит, один дополняющая подписанная форма, sizeof (char) == sizeof (short) == sizeof (int) == sizeof (long) == 4, 48-битные или 9-разрядные char как экзотические архитектуры, о которых заботятся комитеты по стандартам, и список платформы, поддерживаемые стандартом C

Точка о длинном int выше полностью неверна. Большинство Linux/Unix реализация определяет длинный как 64-битный тип, но только 32 бита в Windows, потому что они используют разные модели данных (см. таблица 64-разрядные вычисления), и это независимо от 32 или 64-разрядных Версия ОС.

Источник

Ответ 7

Компилятор определяет размер в зависимости от типа оборудования и ОС.

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

Ответ 8

Из Блог Usrmisc:

Стандарт оставляет его полностью до компилятора, что также означает, что один и тот же компилятор может зависеть от параметров и целевой архитектуры.

Итак, вы не можете.

Кстати, long int совпадает с long.

Ответ 9

Короткий ответ: Нет! Вы не можете фиксировать допущения на размер long int. Поскольку стандарт (стандарт C или POSIX) не документирует размер long int (как неоднократно подчеркивалось). Для того, чтобы предоставить пример вашего убеждения, большинство 64-разрядных систем имеют long размером 64! Чтобы максимизировать переносимость, используйте sizeof соответствующим образом.

Используйте sizeof(long int) для проверки размера, он возвращает размер long в байтах. Значение зависит от системы или среды; значение, компилятор определяет размер на основе аппаратного обеспечения и ОС.