Является ли `long` гарантией быть как минимум 32 бит?

По моему чтению стандарта С++ я всегда понимал, что размеры интегральных фундаментальных типов в С++ были следующими:

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

Я вывел это из 3.9.1/2:

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

Кроме того, размер char описывается в 3.9.1/как:

  • [...] достаточно большой для хранения любого элемента базового набора символов реализации.

1.7/1 определяет это более конкретно:

  • Основным блоком памяти в модели памяти C + + является байт. Байт, по меньшей мере, достаточно большой, чтобы содержать любой элемент базового набора символов исполнения и состоит из непрерывной последовательности бит, число которых определяется реализацией.

Это приводит меня к следующему выводу:

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

где sizeof указывает, сколько байтов является типом. Кроме того, определено, сколько бит находится в байте. Большинство из нас, вероятно, используются для работы с 8-битными байтами, но в стандарте говорится, что в байте есть n бит.


В этом сообщении Альф П. Штейнбах говорит:

long гарантируется (минимум) 32 бита.

Это бросается в глаза всему, что я понимаю, размер фундаментальных типов должен быть на С++ в соответствии со стандартом. Обычно я просто отказываюсь от этого утверждения, поскольку новичок ошибается, но поскольку это был Альф, я решил, что стоит исследовать дальше.

Итак, что вы говорите? Является ли долго гарантированным стандартом быть как минимум 32 бита? Если да, будьте конкретны в отношении того, как делается эта гарантия. Я просто этого не вижу.

  • Стандарт С++ специально говорит, что для того, чтобы знать С++, вы должны знать C (1.2/1) 1

  • Стандарт С++ неявно определяет минимальный предел для значений a long может вместить LONG_MIN - LONG_MAX 2

Итак, независимо от того, насколько велик a long, он должен быть достаточно большим, чтобы удерживать LONG_MIN до LONG_MAX.

Но Alf и другие специфичны, что длина должна быть не менее 32 бит. Это то, что я пытаюсь установить. Стандарт С++ является явным, что количество битов в байте не указано (это может быть 4, 8, 16, 42). Каким образом соединение связано с возможностью размещения чисел LONG_MIN-LONG_MAX как минимум 32 бита


(1) 1.2/1: Следующие ссылочные документы являются обязательными для применения этого документа. Для датированных ссылок применяется только указанное издание. Для недатированных ссылок применяется последнее издание ссылочного документа (включая любые поправки).

  • ISO/IEC 2382 (все части), Информационные технологии - Словарь
  • ISO/IEC 9899: 1999, Языки программирования - C
  • ISO/IEC 10646-1: 2000, Информационные технологии. Универсальный многоточечный кодированный набор символов (UCS). Часть 1. Архитектура и базовая многоязычная плоскость.

(2) Определено в <climits> как:

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

Ответы

Ответ 1

Ответ окончательно ДА. Прочтите мой OP и все комментарии, чтобы понять, почему именно, но здесь короткая версия. Если вы сомневаетесь или сомневаетесь в этом, я рекомендую вам прочитать всю тему и все комментарии. В противном случае принимайте это как истину:

  • Стандарт С++ включает части стандарта C, включая определения для LONG_MIN и LONG_MAX
  • LONG_MIN определяется как не более -2147483647
  • LONG_MAX определяется как не менее +2147483647
  • В С++ интегральные типы хранятся в двоичном виде в базовом представлении
  • Для представления -2147483647 и +2147483647 в двоичном формате вам нужно 32 бита.
  • С++ long гарантированно может отображать минимальный диапазон LONG_MIN через LONG_MAX

Поэтому a long должно быть не менее 32 бит 1.

EDIT:

LONG_MIN и LONG_MAX имеют значения с величинами, продиктованными стандартом C (ISO/IEC 9899: TC3) в разделе §5.2.4.2.1:

[...] Их значения, определяемые реализацией, должны быть равны или больше по величине [...] (абсолютное значение) по показанным, с тем же знаком [...]

— minimum value for an object of type long int
LONG_MIN -2147483647 // -(2 ^ 31 - 1)
— maximum value for an object of type long int
LONG_MAX +2147483647 // 2 ^ 31 - 1

1 32 бит: это не означает, что sizeof (long) >= 4, потому что байт не обязательно 8 бит. Согласно Стандарту, байтом является некоторое неопределенное (определенное платформой) количество бит. Хотя большинство читателей найдут это странное, есть реальное оборудование, на котором CHAR_BIT равно 16 или 32.

Ответ 2

С++ использует ограничения, определенные в стандарте C (С++: 18.3.2 (c.limits), C: 5.2.4.2.1):

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

Таким образом, вам гарантировано, что длинный не менее 32 бит.

И если вы хотите следовать длинному кругообороту, чтобы представить LONG_MIN/LONG_MAX с помощью long, вы должны посмотреть на 18.3.1.2 (numeric.limits.members) в стандарте С++:

static constexpr T min() throw(); // Equivalent to CHAR_MIN, SHRT_MIN, FLT_MIN, DBL_MIN, etc.
static constexpr T max() throw(); // Equivalent to CHAR_MAX, SHRT_MAX, FLT_MAX, DBL_MAX, etc.

Я переместил сноски в комментарий, так что это не совсем то, что появляется в стандарте. Но в основном это означает, что std::numeric_limits<long>::min()==LONG_MIN==(long)LONG_MIN и std::numeric_limits<long>::max()==LONG_MAX==(long)LONG_MAX.

Итак, хотя стандарт С++ не указывает побитовое представление (подписанных) отрицательных чисел, он должен либо быть двухкомпонентным, либо содержать всего 32 бита хранилища, либо он имеет явный бит знака, что означает что он также имеет 32-разрядную память.

Ответ 3

Стандарт С++ отмечает, что содержимое <climits> совпадает с заголовком C <limits.h> (18.2.2 в документе ISO С++ 03).

К сожалению, у меня нет копии стандарта C, существовавшего до С++ 98 (т.е. C90), но в C99 (раздел 5.2.4.2.1) <limits.h> должен иметь как минимум этот минимум значения. Я не думаю, что это изменилось с C90, кроме C99, добавив типы long long.

— minimum value for an object of type long int

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

— maximum value for an object of type long int

LONG_MAX +2147483647 // 2^31 − 1

— maximum value for an object of type unsigned long int

ULONG_MAX 4294967295 // 2^32 − 1

— minimum value for an object of type long long int

LLONG_MIN -9223372036854775807 // −(2^63− 1)

Ответ 4

Но Alf и другие специфичны, что длиной должно быть не менее 32 бит. Это что я пытаюсь установить. С++ Стандарт явствует, что число бит в байте не указывается. Может быть 4, 8, 16, 42... Итак, как соединение, сделанное из размещать номера LONG_MIN-LONG_MAX - не менее 32 биты?

Вам нужно 32 бита в представлении значений, чтобы получить хотя бы это множество битпаттернов. А поскольку С++ требует двоичного представления целых чисел (явный язык для этого эффекта в стандарте, §3.9.1/7), Q.E.D.

Ответ 5

Да, стандарт С++ является явным, что количество бит в байте не указано. Число битов в long также не указано.

Установка нижней границы на число не с указанием.

Стандарт С++ говорит в одном месте:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

Он говорит, по сути, в другом месте, посредством включения стандарта C:

CHAR_BITS >= 8; SHORT_BITS >= 16; INT_BITS >= 16; LONG_BITS >= 32

(за исключением того, что AFAIK, идентификаторы SHORT_BITS, INT_BITS и LONG_BITS не существуют, и эти ограничения определяются требованиями к минимальным значениям для типов.)

Это следует из того факта, что определенное число битов требуется математически для кодирования всех значений в диапазоне (например, для длин) LONG_MIN..LONG_MAX.

Наконец, шорты, ints и longs должны состоять из целого числа символов; sizeof() всегда сообщает интегральное значение. Кроме того, итерация через память char на char должна иметь доступ к каждому биту, что создает некоторые практические ограничения.

Эти требования не противоречат друг другу. Любые размеры, удовлетворяющие требованиям, в порядке.

Были машины давно, с родным словом размером 36 бит. Если вы должны были передать ему компилятор С++, вы можете на законных основаниях принять 9 бит в char, 18 как в short, так и в int и 36 в long. Вы также можете юридически решить иметь по 36 бит в каждом из этих типов по той же причине, что и 32 бита в 32-битной системе. Существуют реалии реального мира, которые используют 64-битные символы.

См. также разделы 26.1-6 и 29.5 С++ FAQ Lite.