Почему компиляторы C указывают, что long должен быть 32-битным, а long long - 64-битным?

Разве не имело бы смысла делать длинные 64-битные и резервировать длинные длинные, пока 128-битные числа не станут реальностью?

7 ответов

Решение

Да, это имеет смысл, но у Microsoft были свои причины для определения "long" как 32-битных.

Насколько я знаю, из всех основных систем на данный момент Windows является единственной ОС, в которой "long" является 32-битным. В Unix и Linux он 64-битный.

Все компиляторы для Windows будут компилировать "длинные" до 32-битных в Windows, чтобы поддерживать совместимость с Microsoft.

По этой причине я избегаю использования "int" и "long". Иногда я буду использовать "int" для кодов ошибок и логических значений (в C), но я никогда не буду использовать их для любого кода, который зависит от размера типа.

Стандарт c НЕ определил длину в битах примитивного типа данных, а только наименьшую длину в битах. Таким образом, компиляторы могут иметь параметры длины битов примитивных типов данных. При определении длины битов каждого примитивного типа данных разработчик компилятора должен учитывать несколько факторов, включая архитектуру компьютера.

Вот несколько ссылок: http://en.wikipedia.org/wiki/C_syntax

Для истории, включая то, почему системы UNIX обычно сошлись на LP64, и почему Windows этого не сделала (большая кодовая база, которая имела int 16 и long 32), и различные аргументы: Долгий путь к 64 битам - Двойной, двойной, тяжелый труд и проблемы — Шекспир, Макбет https://queue.acm.org/detail.cfm?id=1165766 Queue 2006 ИЛИ https://dl.acm.org/doi/pdf/10.1145/1435417.1435431 CACM 2009

Примечание: я участвовал в разработке 64/32-битного MIPS R4000, предложил идею, которая привела к <inttypes.h>, и написал длинный раздел мотивации для C99.

По историческим причинам. В течение долгого времени (каламбур) "int" означало 16-битный; следовательно "длинный" как 32-битный. Конечно, времена изменились. Отсюда "долго-долго":)

PS:

GCC (и другие) в настоящее время поддерживают 128-битные целые числа как "(u) int128_t".

PPS:

Вот обсуждение того, почему люди в GCC приняли решения, которые они сделали:

http://www.x86-64.org/pipermail/discuss/2005-August/006412.html

d 32-разрядные микрокомпьютеры определяют "char" как 8 битов, "short" как 16 битов и "long" как 32 бита. Единственная разница между ними заключается в том, является ли int целым 16 битами или 32.

В то время как 32-разрядный или больший процессор может использовать "int" в качестве 32-разрядного типа, оставляя "long" доступным как 64-разрядный тип, существует существенный корпус кода, который ожидает, что "long" будет 32-разрядным. В то время как Стандарт C добавил типы "фиксированного размера" в 1999 году, в Стандарте есть и другие места, в которых все еще используются "int" и "long", такие как "printf". В то время как C99 добавил макросы для

Еще со времен первого компилятора C для перепрограммируемого микрокомпьютера общего назначения в коде часто было необходимо использовать типы, содержащие ровно 8, 16 или 32 бита, но до 1999 года стандарт не предоставлял явно любой способ для программ, чтобы указать это. С другой стороны, почти все компиляторы для 8-битных, 16-битных и 32-битных микрокомпьютеров определяют "char" как 8 бит, "short" как 16 бит и "long" как 32 бит. Единственная разница между ними заключается в том, является ли int целым 16 битами или 32.

В то время как 32-разрядный или больший процессор может использовать "int" в качестве 32-разрядного типа, оставляя "long" доступным как 64-разрядный тип, существует существенный корпус кода, который ожидает, что "long" будет 32-разрядным. В то время как Стандарт C добавил типы "фиксированного размера" в 1999 году, в Стандарте есть и другие места, которые по-прежнему используют "int" и "long", например "printf". В то время как C99 добавил макросы для предоставления правильных спецификаторов формата для целочисленных типов фиксированного размера, существует значительный объем кода, который ожидает, что "%ld" является допустимым спецификатором формата для int32_t, поскольку он будет работать практически на любых 8-битных 16-битная или 32-битная платформа.

Независимо от того, имеет ли смысл иметь "long" равным 32 битам, из уважения к существующей кодовой базе на протяжении десятилетий или 64 бит, чтобы избежать необходимости более подробного "long long" или "int64_t" для идентификации 64-битные типы - это, вероятно, вызов для суждения, но, учитывая, что новый код должен, вероятно, отдавать предпочтение использованию типов указанного размера, когда это практически возможно, я не уверен, что вижу убедительное преимущество в создании "длинных" 64-битных, если только "int" также 64 бит (что создаст еще большие проблемы с существующим кодом).

C99 N1256 стандартная тяга

Размеры long а также long long определены реализации, все, что мы знаем:

  • минимальный размер гарантии
  • относительные размеры между типами

5.2.4.2.1 Размеры целочисленных типов<limits.h> дает минимальные размеры:

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

  • UCHAR_MAX 255 // 2 8 - 1
  • USHRT_MAX 65535 // 2 16 - 1
  • UINT_MAX 65535 // 2 16 - 1
  • ULONG_MAX 4294967295 // 2 32 - 1
  • ULLONG_MAX 18446744073709551615 // 2 64 - 1

6.2.5 Типы тогда говорят:

8 Для любых двух целочисленных типов с одинаковыми знаками и разным целочисленным рангом преобразования (см. 6.3.1.1) диапазон значений типа с меньшим целочисленным рангом преобразования является поддиапазоном значений другого типа.

и 6.3.1.1 Boolean, символы и целые числа определяют относительные ранги преобразования:

1 Каждый целочисленный тип имеет ранг целочисленного преобразования, определенный следующим образом:

  • Ранг long long int должен быть больше, чем ранг long int, который должен быть больше, чем ранг int, который должен быть больше, чем ранг short int, который должен быть больше, чем ранг подписанного символа char.
  • Ранг любого целого типа без знака должен равняться рангу соответствующего целого типа со знаком, если таковой имеется.
  • Для всех целочисленных типов T1, T2 и T3, если T1 имеет больший ранг, чем T2, и T2 имеет больший ранг, чем T3, то T1 имеет больший ранг, чем T3
Другие вопросы по тегам