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

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

  • Компилятор
  • Процессор
  • Среда разработки

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

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


person Alok Save    schedule 30.12.2010    source источник
comment
Вы имеете в виду примитивные (или встроенные) типы или на самом деле типы POD (структуры, объединения)?   -  person Alex B    schedule 30.12.2010
comment
@Alex, @Als: Важный вопрос.   -  person John Dibling    schedule 30.12.2010
comment
возможный дубликат C ++: размер int, long и т. д.   -  person dmckee --- ex-moderator kitten    schedule 31.12.2010


Ответы (6)


Я думаю, что этот вопрос состоит из двух частей:

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

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

person Alex B    schedule 30.12.2010
comment
Следует отметить, что подавляющее большинство реализаций для основных систем пытаются придерживаться существующей спецификации ABI, которая определяет размеры и формат большинства или всех типов, чтобы облегчить совместимость между различными инструментами или разными версиями одного и того же инструмента. - person R.. GitHub STOP HELPING ICE; 30.12.2010
comment
Компиляторы или реализации старайтесь использовать размеры, которые наиболее эффективны для платформы. На 16-битных платформах компилятор может использовать 16-битные для char, потому что это эффективно с процессором. - person Thomas Matthews; 30.12.2010
comment
@Thomas: размер char определяется самим стандартом, который равен 1. Пожалуйста, посмотрите мой пост. - person Nawaz; 30.12.2010
comment
@Nawaz, sizeof char всегда равно единице, однако CHAR_BIT может быть ›= 8, поэтому фактический размер char в битах будет больше 8. - person Alex B; 31.12.2010
comment
@Alex: тогда что означает sizeof (char) == 1, если бит может быть больше 8? - person Nawaz; 31.12.2010
comment
@R .. Я пытался найти еще кое-что об этом, но не был уверен. Можете ли вы привести пример ABI, который явно определяет размер типа данных C? Все требования, которые я могу найти, - это такие вещи, как требования к выравниванию n-битных данных (без явной ссылки на фактические типы данных C). - person Alex B; 31.12.2010
comment
@Alex: что ты имеешь в виду под правильным? что ты прав? или я? - person Nawaz; 31.12.2010
comment
@ Nawaz о, я неправильно тебя понял. Это означает, что char - это байт (минимальная адресуемая единица памяти), но не обязательно октет. Прочтите мой ответ по ссылке. - person Alex B; 31.12.2010
comment
SVR4 i386 ABI определяет размер всех типов, как и LSB (Linux Standard Base) ABI для i386. Вы можете найти гораздо больше у различных поставщиков проприетарных Unix. И, конечно же, Windows ABI имеет определенные размеры шрифтов. - person R.. GitHub STOP HELPING ICE; 31.12.2010
comment
@Alex: CHAR_BIT всегда равен 8. Он определен самим стандартом. Кто вам сказал, что это значение может быть отличным от 8? - person Nawaz; 31.12.2010
comment
@Nawaz, нет, стандарт C не требует этого, он только подразумевает, что он должен быть не менее 8 (из-за допустимого диапазона значений char). Только POSIX требует, чтобы он был ровно 8-битным. Вот выдержка из стандартного комментария к C99: C не привязан к 8-битному байту, хотя это значение неявно присутствует в большом проценте написанного в нем источника. [...] Некоторые микросхемы DSP имеют 16- или 32-битный тип символа (это больше связано с проблемами адресуемости, чем с размерами набора символов). - person Alex B; 31.12.2010
comment
@Alex: это интересная цитата. не могли бы вы рассказать мне и о разделе, чтобы я мог видеть себя и читать соответствующие материалы? - person Nawaz; 31.12.2010
comment
@Nawaz Это из комментария. В фактическом стандарте это в разделе 5.2.4.2.1 (1): значения, приведенные ниже, должны быть заменены константными выражениями, подходящими для использования в директивах предварительной обработки #if. [...] Их значения, определяемые реализацией, должны быть равны или больше по величине (абсолютному значению) показанным, с тем же знаком. Также в Приложении E: Пределы реализации. - person Alex B; 02.01.2011

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

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


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


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

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

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

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


РЕДАКТИРОВАТЬ:

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

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


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

person Community    schedule 30.12.2010
comment
@Nawaz: Согласитесь и тоже так подумайте ... Просто нужен окончательный вывод! :) - person Alok Save; 30.12.2010
comment
Строго говоря, это зависит только от компилятора. ЦП просто влияет на то, какой макет будет более эффективным, но компилятор, в принципе, может делать все, что ему заблагорассудится. Он не обязан соблюдать требования к выравниванию ЦП, размеры регистров или что-то еще, если он генерирует работающий код. - person jalf; 30.12.2010
comment
@jalf: Хотя некоторые архитектуры действительно неумолимы, когда дело доходит до выравнивания данных (например, IA64). - person In silico; 30.12.2010
comment
@In silico: это просто означает, что компилятор должен сгенерировать дополнительный код для его обработки. (Он может выполнить две выровненные загрузки, а затем объединить результат в регистры. Конечно, дорого, но он позволяет компилятору выполнять невыровненные загрузки даже на процессорах, которые не поддерживают его напрямую) - person jalf; 30.12.2010
comment
@jalf: А, я понимаю, о чем вы. Я возражал против утверждения, что оно не обязательно должно соответствовать требованиям выравнивания ЦП. - person In silico; 30.12.2010
comment
@jalf: Поскольку компилятор построен на базовой архитектуре, вы не можете сказать, что это не влияет на его выбор! Это только вопрос выражения, если вы говорите, что это зависит ТОЛЬКО от компилятора, это означает только то, что если компилятор хочет, он может реализовать sizeof (int) = 128. Но это не так, поскольку он уважает архитектуру! Фактически, он должен уважать архитектуру, если он хочет создать эффективный код! - person Nawaz; 30.12.2010
comment
@Nawaz: Теперь вы перемещаете стойки ворот. Никто ничего не сказал о эффективном коде. Конечно, компилятор, пытающийся сгенерировать быстрый код, должен будет учитывать процессор. Но OP не спрашивал об эффективности, и компилятор, который хочет снизить производительность мог определить sizeof(int) равным 15, а его выравнивание - 5. Это было бы медленно, но компилятор мог просто сгенерировать код, чтобы заставить его работать. - person jalf; 30.12.2010
comment
@In silico: да, это немного вводило в заблуждение. Конечно, код, сгенерированный компилятором, должен соответствовать требованиям ЦП, но типы данных C ++ не должны напрямую отображаться в регистры ЦП или требования к выравниванию. - person jalf; 30.12.2010
comment
@jalf: Я уверен, что автор темы не хочет знать о том, чего не существует в реальном мире. Все, что я говорю, это то, что в реальном мире программирования базовая архитектура действительно влияет на выбор компилятора, точно так же, как ваш банковский баланс влияет на ваш выбор вещей, которые вы покупаете в супермаркете. :-) - person Nawaz; 30.12.2010
comment
@Nawaz: Я никогда этого не отрицал. Я просто подумал, что стоит дать точный ответ: тот, который оба упоминает, что произойдет в реальном мире из-за проблем с эффективностью, и что фактически требуется по стандарту. - person jalf; 30.12.2010
comment
Он действительно спросил, от чего точно зависит размер POD. И единственный точный ответ - это компилятор, и ничего больше. - person jalf; 30.12.2010
comment
@jalf: мир не прерывистый, как вы думаете. Обычный парень может сказать, что поведение ребенка зависит от его воспитания, а биолог может сказать, что это зависит еще и от его гена. Оба верны, пока не противоречат друг другу! - person Nawaz; 30.12.2010
comment
Как именно это зависит только от компилятора и от того, что компилятор и процессор не противоречат друг другу? Если бы я спросил точно, от чего зависит поведение ребенка, то оба эти ответа были бы неверными, потому что это зависит от нескольких факторов. - person jalf; 30.12.2010
comment
@jalf: да, существование самого компилятора зависит от машины, на которой он работает. Таким образом, все, что делает или может делать компилятор, определяется машиной, на которой он работает. Точно так же, как вы не можете летать, поскольку ген и другие вещи, из которых вы сделаны, не поддерживают «полет»! - person Nawaz; 30.12.2010
comment
@Nawaz: не совсем так, потому что любой компилятор можно заставить работать на любом процессоре с полным тьюрингом и генерировать код для любого полного по тьюрингу ПРОЦЕССОР. Итак, на самом деле вы говорите, что это зависит от компилятора и наличия компьютера, что ... даже неправда, потому что я мог бы все это записать на бумаге, если бы у меня было время и терпение. - person jalf; 30.12.2010
comment
@jalf: это круто Я мог бы все это записать на бумаге, если бы у меня было время и терпение ... что означает, что это не зависит даже от компилятора; это полностью зависит от автора компилятора, который принимает актуальное решение о размере встроенных типов и POD. - person Nawaz; 30.12.2010
comment
Размер встроенных типов стандартом не определен; определяется диапазон допустимых значений. Исключение составляет char, размер которого равен 1 (размер определяется компилятором). - person Thomas Matthews; 30.12.2010
comment
@ Томас: кто сказал, что это определено стандартом? - person Nawaz; 30.12.2010

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

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

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

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

person Matteo Italia    schedule 30.12.2010

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

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

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

Просто было бы намного медленнее.

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

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

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

person jalf    schedule 30.12.2010
comment
Компилятор должен определить размеры типов, чтобы соответствовать диапазонам, указанным в Стандарте. Для 8-битной (октетной) платформы компилятору потребуется как минимум два октета, чтобы соответствовать спецификации диапазона для целого числа. - person Thomas Matthews; 30.12.2010
comment
Конечно. Об этом я сказал в последнем абзаце. Он должен сгенерировать исполняемый файл, который следует семантике C ++ (который, среди прочего, определяет минимальные размеры для определенных типов данных) - person jalf; 05.01.2011

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

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

person Prasoon Saurav    schedule 30.12.2010
comment
FWIW, компилятор должен выделить достаточно битов, чтобы выделить диапазоны, указанные в стандарте (спецификации) языка C. Если компилятор хочет использовать 1024 бита для целого числа, он может и по-прежнему соответствовать стандарту. - person Thomas Matthews; 30.12.2010

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

person xyz    schedule 30.12.2010