Что такое тип данных uintptr_t
Что такое uintptr_t и для чего его можно использовать?
- Адрес массива
- Это неуказанное поведение для сравнения указателей с разными массивами для равенства?
- Что происходит, когда вы удаляете указатель дважды или больше на C ++?
- Указатель на 2d-массив
- Почему я не могу обработать массив как указатель в C?
- Являются ли a, & a, a, a , & a и & a одинаковыми указателями?
- Массив для разметки указателя и передачи многомерных массивов в функции
- Инициализация указателя в отдельной функции в C
Это unsigned int, способный хранить указатель. Обычно это означает, что он имеет тот же размер, что и указатель.
Он может быть определен в стандартах C ++ 11 и более поздних версий.
Общей причиной того, что требуется целочисленный тип, который может содержать тип указателя архитектуры, – это выполнять целые операции с указателем или скрывать тип указателя, предоставляя его как целочисленный «дескриптор».
Редактировать: Обратите внимание, что у Стива Джессопа есть некоторые очень интересные дополнительные детали (которые я не буду красть) в другом ответе здесь для вас, педантичных типов 🙂
Во-первых, в то время, когда задавался вопрос, uintptr_t
не был на C ++. Он находится в C99, в
, в качестве необязательного типа. Многие компиляторы C ++ 03 предоставляют этот файл. Он также находится в C ++ 11, в
, где снова он является необязательным, и который относится к C99 для определения.
В C99 он определяется как «целочисленный тип без знака с тем свойством, что любой действительный указатель на void может быть преобразован в этот тип, а затем преобразован обратно в указатель на void, и результат будет сравниваться с исходным указателем».
Возьмите это, чтобы понимать, что он говорит. Он ничего не говорит о размере.
uintptr_t
может быть того же размера, что и void*
. Это может быть больше. Вероятно, это может быть меньше, хотя такая реализация на C ++ приближается к извращению. Например, на некоторой гипотетической платформе, где void*
– 32 бита, но используется только 24 бита виртуального адресного пространства, вы можете получить 24-разрядный uintptr_t
который удовлетворяет этому требованию. Я не знаю, почему реализация будет делать это, но стандарт позволяет это.
Это целое число без знака, равное размеру указателя. Всякий раз, когда вам нужно делать что-то необычное с помощью указателя – например, инвертировать все биты (не спрашивайте, почему), вы uintptr_t
его на uintptr_t
и манипулируете им как обычное целое число, а затем отбрасываете.
Уже есть много хороших ответов на часть «что такое тип данных uintptr_t». Я попытаюсь решить, для чего он может быть использован? в этом посте.
В основном для побитовых операций с указателями. Помните, что в C ++ нельзя выполнять побитовые операции с указателями. По причинам см. Почему вы не можете выполнять побитовые операции с указателем в C, и есть ли способ обойти это?
Таким образом, для выполнения поразрядных операций над указателями нужно было бы наложить указатели на тип unitpr_t, а затем выполнить побитовые операции.
Вот пример функции, которую я только что написал, чтобы сделать побитовое исключение или 2 указателя для хранения в связанном списке XOR, чтобы мы могли перемещаться в обоих направлениях, как дважды связанный список, но без штрафа за сохранение 2 указателей в каждом узле ,
template T* xor_ptrs(T* t1, T* t2) { return reinterpret_cast(reinterpret_cast(t1)^reinterpret_cast (t2)); }