#c #c 11
#c #c 11
Вопрос:
Я использую size_t
для целых чисел без знака в своем коде. Это имеет преимущество, если мой компьютер поддерживает 64-разрядную версию, size_t
будет unsigned long long int
, в противном случае, это так unsigned int
. Мой код может работать как на 32-разрядной, так и на 64-разрядной платформе.
Существует ли аналогичное целое число со знаком? Если платформа поддерживает только 32-разрядную версию, это так int
, если платформа поддерживает 64-разрядную версию, это так long long int
.
Я могу добиться этого, установив флаг:
#ifdef USE_INT64
#define MY_INT int
#else
#define MY_INT long long int
#endif
Затем используйте MY_INT
. Однако мне нужно определить USE_INT64
и включить этот заголовок для всего моего кода. Если есть что-то похожее на size_t
, это будет здорово.
Комментарии:
1.
uint64_t
Может быть, использовать вместо этого?2. В cstdint есть целая куча целочисленных типов ( en.cppreference.com/w/cpp/header/cstdint ). Выберите подходящий.
3. Начиная с C 11, все соответствующие компиляторы C поддерживают 64-разрядные целые числа. Учитывая это, может быть разумно использовать 32-разрядные целые числа в одних системах и 64-разрядные целые числа в других — но сначала вы должны определить, как вы хотите сделать этот выбор. См. Также
<cstdint>
стандартный заголовок, который определяет целочисленные типы с точной шириной, а также «быстрые» и «наименьшие» типы, по крайней мере , с указанной шириной.int_fast32_t
может быть то, что вы хотите.4.
ptrdiff_t
это знаковый тип, который, вероятно, будет 32-разрядным в «32-разрядных» системах и 64-разрядным в «64-разрядных» системах, но я бы не стал использовать его для этой цели. Это тип результата вычитания указателя, и единственная гарантия заключается в том, что он не менее 17 бит.
Ответ №1:
Если вы хотите привязать свои типы непосредственно к ширине адреса, тогда типы, которые вы ищете, называются uintptr_t
и intptr_t
. Они наследуются из стандартной библиотеки C через <cstdint>
.
Тип size_t
не гарантируется иметь тот же размер, что и указатель (в общем случае он меньше), что означает, что его удобство для этой цели зависит от платформы. (Читайте: хотя это будет работать везде, это концептуально неверно.)
Конечно, реальный вопрос здесь заключается в том, есть ли веская основная причина привязать ваш целочисленный тип к ширине адреса. Если нет, лучшей идеей было бы определить ваши типы непосредственно через uintNN_t
/ intNN_t
typedefs и забыть о size_t
и тому подобное.
Ответ №2:
Существует соответствующий подписанный тип ptrdiff_t
, который определен для учета разницы между двумя указателями. Он должен быть того же размера, что и указатель, как size_t
есть.
Комментарии:
1.«Тот же размер, что и указатель»
uintptr_t
. Реализация может решить сделатьptrdiff_t
больше, чем указатель, чтобы позволить пользователю вычитать любые указатели.size_t
обычно меньше указателя.2. @AnT Я не думаю, что видел реализацию, в которой
size_t
orptrdiff_t
имеет размер, отличный от указателя, но яintptr_t
полностью забыл об этом. 1 к вашему собственному ответу.
Ответ №3:
Вы могли бы использовать std::make_signed
, чтобы получить точный подписанный аналог тому, что std::size_t
для unsigned:
using fancy_signed = std::make_signed<std::size_t>::type;