Какая разница между size_t и int в С++?

В нескольких примерах C++ я вижу использование типа size_t, где я бы использовал простой int. Какая разница, и почему size_t должен быть лучше?

Ответ 1

Из дружественная Википедия:

Заголовочные файлы stdlib.h и stddef.h определяют тип данных size_t, который используется для представления размера объекта. Функции библиотеки, которые принимают размеры, предполагают, что они имеют тип size_t, а оператор sizeof оценивает size_t.

Фактический тип size_t зависит от платформы; распространенная ошибка заключается в том, чтобы предположить, что size_t является таким же, как unsigned int, что может привести к ошибкам программирования, особенно в том случае, когда 64-разрядные архитектуры становятся более распространенными.

Кроме того, проверьте Почему size_t имеет значение

Ответ 2

size_t - это тип, используемый для представления размеров (как следует из его названий). Его платформа (и даже потенциальная реализация) зависит и должна использоваться только для этой цели. Очевидно, что, представляя размер, size_t не имеет знака. Многие функции stdlib, включая функции malloc, sizeof и различные строки, используют size_t в качестве типа данных.

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

Подводя итог: используйте size_t для представления размера объекта и int (или long) в других случаях.

Ответ 3

Это потому, что size_t может быть чем-то другим, кроме int (возможно, struct). Идея состоит в том, что она отделяет это задание от базового типа.

Ответ 4

Тип size_t определяется как неподписанный интегральный тип оператора sizeof. В реальном мире вы часто видите int, определяемый как 32 бит (для обратной совместимости), но size_t, определяемый как 64 бита (чтобы вы могли объявлять массивы и структуры размером более 4 GiB) на 64-битных платформах. Если a long int также является 64-битным, это называется соглашением LP64; если long int - 32 бита, но long long int, а указатели - 64 бита, то есть LLP64. Вы также можете получить обратную, программу, которая использует 64-битные инструкции для скорости, но 32-разрядные указатели для экономии памяти. Кроме того, int подписан и size_t не имеет знака.

Исторически существовало множество других платформ, где адреса были более широкими или короче, чем собственный размер int. Фактически, в 70-х и начале 80-х годов это было более распространено, чем нет: все популярные 8-битные микрокомпьютеры имели 8-битные регистры и 16-разрядные адреса, а переход между 16 и 32 битами также вызывал множество машин, у которых были адреса чем их регистры. Я иногда все еще вижу здесь вопросы о Borland Turbo C для MS-DOS, в режиме огромной памяти которого 20-разрядные адреса хранятся в 32 битах 16-разрядного ЦП (но которые могут поддерживать 32-разрядный набор команд 80386); Motorola 68000 имела 16-битный ALU с 32-разрядными регистрами и адресами; были мэйнфреймы IBM с 15-битными, 24-битными или 31-битными адресами. Вы также по-прежнему видите разные размеры ALU и адресной шины во встроенных системах.

В любое время int меньше, чем size_t, и вы пытаетесь сохранить размер или смещение очень большого файла или объекта в unsigned int, существует вероятность того, что он может переполняться и вызвать ошибку. При int существует также возможность получить отрицательное число. Если число int или unsigned int шире, программа будет работать правильно, но потеряет память.

Обычно вы должны использовать правильный тип, если хотите переносить. Многие люди будут рекомендовать вам использовать подписанную математику вместо unsigned (чтобы избежать неприятных, тонких ошибок, таких как 1U < -3). Для этой цели стандартная библиотека определяет ptrdiff_t в <stddef.h> как подписанный тип результата вычитания указателя из другого.

Тем не менее, обходной путь может быть связан с ограничениями - проверьте все адреса и смещения на INT_MAX и либо 0, либо INT_MIN, если это необходимо, и включите предупреждения компилятора о сравнении подписанных и неподписанных величин в случае, если вы пропустите Любые. Вы всегда должны всегда всегда проверять доступ к массиву для переполнения в C.

Ответ 5

Определение SIZE_T находится по адресу: https://msdn.microsoft.com/en-us/library/cc441980.aspx и https://msdn.microsoft.com/en-us/library/cc230394.aspx

Вставка здесь необходимой информации:

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

Этот тип объявляется следующим образом:

typedef ULONG_PTR SIZE_T;

A ULONG_PTR - это беззнаковый длинный тип, используемый для точности указателя. Он используется при наведении указателя на длинный тип для выполнения арифметики указателя.

Этот тип объявляется следующим образом:

typedef unsigned __int3264 ULONG_PTR;