c автоматический 64-разрядный целочисленный тип

#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 or ptrdiff_t имеет размер, отличный от указателя, но я intptr_t полностью забыл об этом. 1 к вашему собственному ответу.

Ответ №3:

Вы могли бы использовать std::make_signed , чтобы получить точный подписанный аналог тому, что std::size_t для unsigned:

 using fancy_signed = std::make_signed<std::size_t>::type;