беззнаковый Инт и размер Т



Я замечаю, что современный код C и c++, кажется, использует size_t вместо int/unsigned int практически везде - от параметров для строковых функций C до STL. Мне любопытно, в чем причина этого и какие преимущества это приносит.

619   8  

8 ответов:

The size_t тип-это целочисленный тип без знака, который является результатом sizeof оператор (и offsetof оператор), поэтому он гарантированно будет достаточно большим, чтобы содержать размер самого большого объекта, который может обрабатывать ваша система (например, статический массив 8 ГБ).

The size_t тип может быть больше, равна или меньше unsigned int и ваш компилятор может делать предположения о его оптимизации.

вы можете найти более точную информацию в C99 стандарт, раздел 7.17, проект которого доступен в Интернете в pdf формат, или в стандарте C11, раздел 7.19, также доступный как PDF файл проекта.

классический C (ранний диалект C, описанный Брайаном Керниганом и Деннисом Ричи в языке программирования C, Prentice-Hall, 1978) не обеспечивал size_t. Комитет по стандартам C представил size_t для устранения проблемы переносимости

подробно объяснил на embedded.com (с очень хорошим примером)

короче, size_t никогда не является отрицательным, и это максимизирует производительность, потому что typedef'D должен быть целочисленным типом без знака, который достаточно велик, но не слишком велик, чтобы представлять размер самого большого возможного объекта на целевой платформе.

размеры никогда не должны быть отрицательными, и действительно size_t - Это тип без знака. Кроме того, потому что size_t без знака, вы можете хранить числа, которые примерно в два раза больше, чем в соответствующем знаковом типе, потому что мы можем использовать знаковый бит чтобы представить величину, как и все другие биты в целочисленном без знака. Когда мы получаем еще один бит, мы умножаем диапазон чисел, которые мы можем представить, примерно в два раза.

Итак, вы спрашиваете, почему бы просто не использовать unsigned int? Он может быть не в состоянии содержать достаточно большие числа. В реализации, где unsigned int 32 бита, самое большое число оно может представить 4294967295. Некоторые процессоры, такие как IP16L32, могут копировать объекты размером больше 4294967295 байт.

так, вы спросите, почему бы не использовать unsigned long int? Это приводит к снижению производительности на некоторых платформах. Стандарт C требует, чтобы a long занимать не менее 32 бит. Платформа IP16L32 реализует каждый 32-бит длиной в пару 16-битных слов. Почти все 32-битные операторы на этих платформах требуют двух инструкций, если не больше, потому что они работают с 32 битами в двух 16-битных блоках. Например, для перемещения 32-битной длины обычно требуется две машинные инструкции - по одной для перемещения каждого 16-битного фрагмента.

используя size_t предотвращает потери производительности. Согласно эта фантастическая статья "тип size_t - Это typedef, который является псевдонимом для некоторого целочисленного типа без знака, обычно unsigned int или unsigned long, но и, возможно, даже unsigned long long. Каждая стандартная реализация C должна выбрать целое число без знака, которое достаточно велико,но не больше, чем необходимо, чтобы представить размер самого большого возможного объекта на целевой платформе."

тип size_t-это тип, возвращаемый оператором sizeof. Это целое число без знака, способное выражать размер в байтах любого диапазона памяти, поддерживаемого на главной машине. Это(как правило) связано с ptrdiff_t в том, что ptrdiff_t является целочисленным значением со знаком, таким что sizeof(ptrdiff_t) и sizeof (size_t) равны.

при написании кода C вы должны всегда используйте size_t при работе с диапазонами памяти.

тип int с другой стороны в основном определяется как размер (подписанного) целочисленного значения, которое хост-машина может использовать для наиболее эффективного выполнения целочисленной арифметики. Например, на многих старых компьютерах PC Тип значения оператор sizeof(size_t), так было бы 4 (байта), но оператор sizeof(тип int) будет 2 (байта). 16 битная арифметика была быстрее, чем 32-битная арифметика, хотя процессор мог обрабатывать (логической) памяти до 4 Гб.

используйте тип int только тогда, когда вы заботитесь об эффективности, поскольку его фактическая точность зависит сильно зависит как от параметров компилятора, так и от архитектуры машины. В частности, стандарт C определяет следующие инварианты: sizeof(char)

Примечание: это не то же самое, что в Java (который фактически определяет битовую точность для каждого из типов 'char', 'byte', 'short', 'int' и 'long').

тип size_t должен быть достаточно большим, чтобы хранить размер любого возможного объекта. Unsigned int не должен удовлетворять этому условию.

например, в 64-битных системах int и unsigned int могут быть 32-битными, но size_t должен быть достаточно большим, чтобы хранить числа больше, чем 4G

эта выдержка из руководства glibc 0.02 также может быть актуальна при исследовании темы:

существует потенциальная проблема с типом size_t и версиями GCC до выпуска 2.4. ANSI C требует, чтобы size_t всегда был беззнаковым типом. Для совместимости с заголовочными файлами существующих систем GCC определяет size_t в stddef.h' to be whatever type the system'ssys / types.ч' определяет его. Большинство систем Unix, которые определяют size_t в ' sys / types.сек, определить его тип. Некоторый код в библиотеке зависит на size_t является беззнаковым типом и не будет работать правильно, если он подписан.

код библиотеки GNU C, который ожидает, что size_t будет без знака, является правильным. Определение size_t, так как подпись типа является неверным. Мы планируем, что в версии 2.4 GCC всегда будет определять size_t как беззнаковый тип, а fixincludes' script will massage the system'ssys / types.ч' чтобы не конфликтовать с этим.

в то же время, мы работаем вокруг этой проблемы, сообщая GCC явно использовать беззнаковый тип для size_t, когда компиляция библиотеки языка Си. "настройка" автоматически определит, какой тип GCC использует для size_t, чтобы при необходимости переопределить его.

если мой компилятор установлен на 32 бит,size_t Это не что иное, как typedef для unsigned int. Если мой компилятор установлен на 64 бит,size_t Это не что иное, как typedef для unsigned long long.

size_t-это размер указателя.

Итак, в 32 битах или общей модели ILP32 (integer, long, pointer) size_t составляет 32 бита. и в 64 битах или общей модели LP64 (long, pointer) size_t составляет 64 бита (целые числа по-прежнему 32 бита).

есть и другие модели, но это те, которые использует g++ (по крайней мере, по умолчанию)

Comments

    Ничего не найдено.