2016-03-07 7 views
64

Всегда ли так, что long int (насколько я понимаю, является синонимом для long) is 4 bytes?Могу ли я предположить, что размер long int всегда равен 4 байтам?

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

+12

Просто напомните вам, что 'sizeof' учитывает отступы и выравнивание. Он соответствует стандарту 'sizeof (unsigned long)' из 8 байтов, но переполнение ведет себя как 4 байта. Это неправильно, если вы пытаетесь использовать 'sizeof' и' CHAR_BITS' для вычисления предела целочисленного типа. Используйте 'limits.h', когда он должен использоваться. – user3528438

+11

Вы действительно должны прочитать (сокращенную первую, а затем полную версию) C-faq, которая возникла в Usenet в то время, когда это было * место, где люди, обладающие знаниями по предмету, собрались в одном и том же месте (теперь, он широко распространен среди нескольких сайтов ...), и поэтому он привел к невероятным результатам и хорошо выполненным часто задаваемым вопросам. См. Http://c-faq.com/versions.html. Чтение - это открывающий глаза на этот вопрос, и на десятки больше вы, вероятно, даже не знаете, о чем вам нужно знать (раздел 5 - нулевые указатели - это тот, который содержит часто задаваемые вопросы, которые я был шокирован (и благодарен)) –

+7

нет, это 8 на моем компьютере – RiaD

ответ

102

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

В стандарте, однако, указывается минимум. Из раздела 5.2.4.2.1 части C Standard:

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

...

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

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

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

    LONG_MAX +2147483647 // 2^31-1

Это говорит о том, что 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 (длинный) = 4

Выход на CentOS 7 x64:

SizeOf (длинный) = 8

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

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

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

+0

Это typedefs как 'uint64_t' не являются частью стандарта до C11. Может быть, вы это скажете. – JojOatXGME

+4

Но эти typedefs в стандарте! Просто реализация определяется, существуют ли они на самом деле и какие типы они представляют! – Vincent

+1

@JojOatXGME 'stdint.h' существует с C99. – user694733

20

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

+2

ИМО, это не отвечает на вопрос. – nouney

+6

Это действительно помогло мне :) – Elimination

+0

@nouney, как заявить, что нет точного размера, гарантированного стандартами C, или стандарты POSIX не отвечают на вопрос? это не лучший ответ, но, конечно, не так. – Leliel

38

Нет, ни стандарт C, ни POSIX не гарантируют это и фактически most Unix-like 64-bit platforms имеют бит 64 бит (8 байт) long.

+0

Ints на большинстве 32-разрядных и выше платформ 32 бит (AFAIK, во всяком случае), что бы было иметь длинный размер такого же размера, как int? В моей системе (Intel, 64-разрядный Linux, gcc) 32 для int, 64 для долгого. – jamesqf

+7

@jamesqf: на подавляющем большинстве платформ, выпущенных в период с 1980 по 2005 год, короткий был 16 бит, длиной 32 бита, а «int» был 16 или 32 бита в удобстве реализации. Имея фиксированные типы для 16 и 32-битных типов до добавления C99, stdint.h был полезен. В качестве приятного дополнительного усложняющего фактора с последним, однако, в системе с 32-битным «int», int32_t может быть совместим с «int» или с «long», но соответствующие реализации не позволяют сделать его совместимым с обоими. – supercat

14

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

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

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

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

sizeof(long int) 

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

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

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

+3

Не (только) аппаратное обеспечение. Вы можете запустить 32-разрядную версию Linux на 64-битном оборудовании, и вы даже можете использовать x32 ABI, где типы данных имеют размер как на 32-битном оборудовании, но аппаратное обеспечение фактически работает в режиме 64 бит. – delnan

+0

@ delnan, yap, это правда. Вероятно, я должен уточнить это, изменив «обычно» на «в основном» и добавив информацию в скобки. – Myst

+0

@ delnan, я не хотел перешагивать через ваш ответ, я просто подумал, что лучше всего пояснить, что 'sizeof' - это директива компилятора, чтобы удалить любые предполагаемые причины, которые могут возникнуть у кого-либо для угадывания размера. – Myst

8

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

Итак, предположения не должны делаться относительно размера.

12

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

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

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

+0

Действительно? По крайней мере, на GCC/Glibc/GNU/Linux платформы, похоже, сходятся на int = 32, long long = 64, long = собственный размер слова (32 или 64) и, конечно, не длинный = 64. на x86, который не является ничейной архитектурой, длинный 32 бит. OSX, Solaris, z/OS, SysV - это некоторые другие ОС, которые следуют этому соглашению. –

+0

Для более широко используемой системы, чем OSX, Linux, z/OS или SysV, есть Windows, у которой есть еще одно другое соглашение, чем ваше (всегда 64) или те (всегда такие же, как указатель), а именно всегда 32 биты. –

+0

ИМХО, правильным средством было бы иметь стандартные средства, с помощью которых код может указывать, какие «int», «long» и т. Д. Требуются в определенных контекстах [обычно для каждого файла, так что заголовочный файл, объявляющий функцию так как принятие «int» всегда будет иметь то же значение]. Наличие 64-битной системы для эмуляции 16-битного или 32-битного «int» должно быть довольно простым, и, вероятно, было бы более надежным, чем попытка настроить код, учитывая все нечетные маленькие нюансы в C (например, тот факт, что на 64 -битная система, модульное умножение uint32_t не работает для всех значений). – supercat

9

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

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

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

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

  • Int> = 16 бит,
  • длинных> = 32 бит,
  • долго долго (поскольку C99)> = 64 бит
  • sizeof (char) < = sizeof (short) < = sizeof (int) < = sizeof (long) < = SizeOf (длинные длинные)
  • SizeOf (Char) == 1
  • CHAR_BIT> = 8

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

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

Source

1

От Usrmisc's Blog:

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

Так вы не можете.

По случаю long int - это то же самое, что и long.

0

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

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

Смежные вопросы