Размер примитивных типов данных

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

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

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

EDIT: Извините за беспорядок. Я хотел спросить о Primitive типе данных, например int, а не о POD. Я понимаю, что POD могут включать в себя структуру и со структурой - это совершенно другая игра с мячом с дополнением к картинке, Я исправил Q, примечание по редактированию здесь должно гарантировать, что ответы на POD не выглядят неуместными.

Ответ 1

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

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

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

Ответ 2

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

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


EDIT: какие стандарты говорят,


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

С++ 03 Стандарт $5.3.3/1 говорит,

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

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


EDIT:

Я нашел этот раздел часто задаваемых вопросов в С++ действительно хорошим. Вся глава. Это очень крошечная глава.: -)

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


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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

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

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

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

Ответ 5

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

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

Ответ 6

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