Размер примитивных типов данных - PullRequest
11 голосов
/ 30 декабря 2010

От чего именно зависит размер примитивного типа данных, например int?

  • Compiler
  • Процессор
  • Среда разработки

Или это сочетание этих или других факторов?
Объяснение причины того же будет очень полезно.

РЕДАКТИРОВАТЬ: Извините за путаницу .. Я хотел спросить о примитивных типах данных, таких как int, а не о POD, я понимаю, что POD могут включать в себя структуру, и со структурой это совершенно другая игра с мячом, в которую входят отступы. , Я исправил вопрос, примечание по редактированию здесь должно гарантировать, что ответы относительно POD не выглядят неуместными.

Ответы [ 6 ]

8 голосов
/ 30 декабря 2010

Я думаю, что на этот вопрос есть две части:

  1. Какие размеры примитивных типов допускаются .
    Это определено стандартами C и C ++ : типы допускают минимальные диапазоны значений, которые они должны иметь, что неявно устанавливает нижнюю границу их размера в битах (например, long must должно быть не менее 32 бит, чтобы соответствовать стандарту).
    Стандарты не определяют размер в байтах, потому что определение байта зависит от реализации, например, char является байтом, но размер байта (CHAR_BIT макрос) может быть 16 бит.

  2. Фактический размер, определенный реализацией.
    Это, как уже указывалось в других ответах, зависит от реализации: компилятора. А реализация компилятора, в свою очередь, находится под сильным влиянием целевой архитектуры. Поэтому вполне возможно иметь два компилятора, работающих на одной ОС и архитектуре, но с разным размером int. Единственное допущение, которое вы можете сделать, это утверждение, установленное стандартом (при условии, что компилятор его реализует).
    Также могут быть дополнительные требования ABI (например, фиксированный размер перечислений).

6 голосов
/ 30 декабря 2010

Прежде всего, это зависит от компилятора. Компилятор, в свою очередь, обычно зависит от архитектуры, процессора, среды разработки и т. Д., Поскольку учитывает их. Так что вы можете сказать, что это комбинация всего. Но я бы НЕ сказал этого. Я бы сказал, Compiler , поскольку на одной и той же машине у вас могут быть разные размеры POD и встроенных типов, если вы используете разные компиляторы. Также обратите внимание, что ваш исходный код вводится в компилятор, поэтому именно этот компилятор принимает окончательное решение о размерах POD и встроенных типов. Однако верно и то, что на это решение влияет базовая архитектура целевой машины. В конце концов, настоящий полезный компилятор должен испускать эффективный код, который в конечном итоге выполняется на целевой машине.

Компиляторы также предоставляют options. Немногие из них могут повлиять на размеры!


РЕДАКТИРОВАТЬ: Что говорят стандарты,


Размер char, signed char и unsigned char определяется самим C ++ Standard! Размеры всех других типов определяются компилятором.

C ++ 03 Standard $ 5.3.3 / 1 говорит,

sizeof (char), sizeof (подписанный char) и sizeof (без знака) 1; результат sizeof применяется к любой другой Основной тип (3.9.1) реализации. [Примечание: в в частности, sizeof (bool) и sizeof (wchar_t) реализация defined.69)

C99 Standard ($ 6.5.3.4) также сам определяет размер char, signed char и unsigned char равным 1, но оставляет размер других типов, определяемых компилятором!


EDIT:

Я нашел эту главу C ++ FAQ действительно хорошей. Вся глава. Это очень маленькая глава, хотя. : -)

http://www.parashift.com/c++-faq-lite/intrinsic-types.html


Также прочитайте комментарии ниже, есть несколько хороших аргументов!

2 голосов
/ 30 декабря 2010

Как я прокомментировал в ответе @ Nawaz, технически он зависит исключительно от компилятора.

Компилятору просто поручено взять действительный код C ++ и вывести действительный машинный код (или любой другой язык, на который он нацелен).

Таким образом, компилятор C ++ может решить сделать int размером 15 и потребовать его выравнивания по 5-байтовым границам, а может решите вставить произвольный отступ между переменными в POD.Ничто в стандарте не запрещает это, и он все еще может генерировать рабочий код.

Это будет намного медленнее.

Так что на практике компиляторы получают некоторые подсказки от системы, в которой они работаютвключается двумя способами: - ЦП имеет определенные предпочтения: например, он может иметь 32-разрядные регистры ширины, поэтому было бы неплохо создать ширину int 32 бита, и для него обычно требуется естественное выравнивание переменных (например, переменная шириной 4 байта должна быть выровнена по адресу, делимому на 4), поэтому компилятор sensible учитывает эти предпочтения, поскольку он дает более быстрый код.- ОС также может иметь какое-то влияние, так как если она использует другой ABI, а не компилятор, выполнение системных вызовов будет излишне трудным.

Но это всего лишь практические соображения, облегчающие жизнь программиста или генерирующие более быстрый код.Они не обязательны .

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

2 голосов
/ 30 декабря 2010

Если вы спрашиваете о размере примитива типа, подобного int, я бы сказал, что это зависит от того фактора, который вы указали.

Пара компилятор / окружение (где среда часто означает ОС), безусловно, является ее частью, поскольку компилятор может по-разному отображать различные «разумные» размеры для встроенных типов по разным причинам: например, компиляторы в Windows x86_64 обычно имеют 32-битную long и 64-битный long long, чтобы избежать нарушения кода для простого x86;в x86_64 Linux вместо этого long обычно 64-битный, потому что это более «естественный» выбор, а приложения, разработанные для Linux, как правило, более независимы от архитектуры (поскольку Linux работает на гораздо большем разнообразии архитектур).

Процессор, безусловно, имеет значение при принятии решения: int должен быть «натуральным размером» процессора, обычно размером регистров общего назначения процессора.Это означает, что этот тип будет работать быстрее в текущей архитектуре.long вместо этого часто рассматривается как тип, который обменивает производительность на расширенный диапазон (это редко встречается на обычных ПК, но на микроконтроллерах это нормально).

Если вместо этого вы также говорите о struct S & Co.(которые, если они уважают некоторые правила, равны POD), опять же, компилятор и процессор влияют на их размер, так как они сделаны из встроенных типов и из соответствующего отступа, выбранного компилятором для достижениялучшая производительность на целевой архитектуре.

0 голосов
/ 30 декабря 2010

A struct также может быть POD, в этом случае вы можете контролировать потенциальную заполненность между элементами с помощью #pragma pack на некоторых компиляторах.

0 голосов
/ 30 декабря 2010

Это зависит от реализации (компилятор).

Implementation-defined behavior означает неопределенное поведение, при котором каждая реализация документирует, как сделан выбор.

...