Всегда ли верно, что long int
(что, насколько я понимаю, является синонимом для long
), это 4
bytes?
Могу ли я полагаться на это? Если нет, это может быть справедливо для ОС на базе POSIX?
Всегда ли верно, что long int
(что, насколько я понимаю, является синонимом для long
), это 4
bytes?
Могу ли я полагаться на это? Если нет, это может быть справедливо для ОС на базе POSIX?
Стандарты ничего не говорят о точном размере любых целых типов, кроме 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-bitint16_t
: подписанный 16-разрядныйuint16_t
: unsigned 16-bitint32_t
: подписанный 32-разрядныйuint32_t
: unsigned 32-bitint64_t
: подписанный 64-разрядныйuint64_t
: неподписанный 64-разрядныйЗаголовок stdint.h
описан в разделе 7.20 стандарта с точными типами ширины в разделе 7.20.1.1. В стандарте указано, что эти typedef являются необязательными, но они существуют в большинстве реализаций.
Нет, ни стандарт C, ни POSIX не гарантируют это, и фактически большинство Unix-подобных 64-разрядных платформ имеют 64-битный (8 байт ) long
.
Используйте код sizeof(long int)
и проверьте размер. Он даст вам размер long int в байтах в системе, в которой вы сейчас работаете. Ответ на ваш вопрос в частности - НЕТ. Это нигде не гарантируется в C или POSIX или где-либо еще.
Как указано @delnan, реализации POSIX сохраняют размер long
и int
как неопределенный и часто различаются между 32-битными и 64-битными системами.
Длина long
в основном связана с аппаратным (часто совпадающим с размером регистров данных на процессоре, а иногда и с другими проблемами, связанными с программным обеспечением, такими как дизайн ОС и интерфейс ABI).
Чтобы облегчить ваш разум, sizeof
не является функцией, а директивой компилятора *, поэтому ваш код не использует операции при использовании sizeof
- он то же самое, что и запись номера, только он переносимый.
использование:
sizeof(long int)
* Как отметил Дэйв в комментариях, sizeof
будет вычисляться во время выполнения, когда невозможно вычислить значение во время компиляции, например, при использовании массивов переменной длины.
Кроме того, как указано в другом комментарии, sizeof
учитывает заполнение и выравнивание, используемые реализацией, что означает, что фактические используемые байты могут отличаться от размера в памяти (это может быть важно при смещении бит).
Если вы ищете конкретные переменные размера байта, подумайте об использовании байтового массива или (я бы предположил, что поддерживаю) типы, определенные C99 в stdint.h
- как предложено @dbush.
Когда мы впервые внедрили C на аппаратном обеспечении ICL Series 39, мы взяли стандарт в своем слове и сопоставили типы данных с естественным представлением на этой машинной архитектуре, которая была short
= 32 бит, int
= 64 бит, long
= 128 бит.
Но мы обнаружили, что никаких серьезных приложений С не работало; все они принимали отображение short
= 16, int
= 32, long
= 64, и нам пришлось сменить компилятор, чтобы поддержать это.
Таким образом, независимо от официального стандарта, в течение многих лет все сходились на long
= 64 бит, и это вряд ли изменится.
стандарт ничего не говорит о размере 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-разрядных Версия ОС.
Компилятор определяет размер в зависимости от типа оборудования и ОС.
Таким образом, не следует делать предположения относительно размера.
Стандарт оставляет его полностью до компилятора, что также означает, что один и тот же компилятор может зависеть от параметров и целевой архитектуры.
Итак, вы не можете.
Кстати, long int
совпадает с long
.
Короткий ответ: Нет! Вы не можете фиксировать допущения на размер long int
. Поскольку стандарт (стандарт C или POSIX) не документирует размер long int
(как неоднократно подчеркивалось). Для того, чтобы предоставить пример вашего убеждения, большинство 64-разрядных систем имеют long
размером 64! Чтобы максимизировать переносимость, используйте sizeof
соответствующим образом.
Используйте sizeof(long int)
для проверки размера, он возвращает размер long
в байтах. Значение зависит от системы или среды; значение, компилятор определяет размер на основе аппаратного обеспечения и ОС.