significado - punteros c++
¿Qué es el tipo de datos uintptr_t? (4)
Es un tipo entero sin signo exactamente del tamaño de un puntero. Siempre que necesite hacer algo inusual con un puntero, como por ejemplo invertir todos los bits (no pregunte por qué), lo uintptr_t
en uintptr_t
y lo manipula como un número entero habitual, y luego lo devuelve.
¿Qué es uintptr_t y para qué se puede usar?
Lo primero, en el momento en que se hizo la pregunta, uintptr_t
no estaba en C ++. Está en C99, en <stdint.h>
, como un tipo opcional. Muchos compiladores de C ++ 03 proporcionan ese archivo. También está en C ++ 11, en <cstdint>
, donde nuevamente es opcional, y se refiere a C99 para la definición.
En C99, se define como "un tipo entero sin signo con la propiedad de que cualquier puntero válido para anular se puede convertir a este tipo, luego se convierte de nuevo en puntero a vacío, y el resultado se comparará igual al puntero original".
Toma esto para significar lo que dice. No dice nada sobre el tamaño.
uintptr_t
puede tener el mismo tamaño que un void*
. Podría ser más grande. Posiblemente podría ser más pequeño, aunque tal implementación de C ++ se aproxima de manera perversa. Por ejemplo, en una plataforma hipotética donde void*
es de 32 bits, pero solo se utilizan 24 bits de espacio de direcciones virtuales, podría tener un uintptr_t
24 bits que cumpla con el requisito. No sé por qué una implementación haría eso, pero el estándar lo permite.
Ya hay muchas respuestas correctas a la parte "cuál es el tipo de datos uintptr_t". Intentaré abordar "para qué se puede usar?" parte en este post
Principalmente para operaciones bitwise en punteros. Recuerde que en C ++ no se pueden realizar operaciones bitwise en los punteros. Por razones, vea ¿Por qué no puede hacer operaciones bitwise en el puntero en C, y hay una manera de evitar esto?
Por lo tanto, para realizar operaciones a nivel de bits en los punteros, habría que convertir los punteros para escribir unitpr_t y luego realizar operaciones a nivel de bits.
Este es un ejemplo de una función que acabo de escribir para hacer bitwise exclusivo o de 2 punteros para almacenar en una lista enlazada XOR para que podamos recorrer en ambas direcciones como una lista doblemente enlazada pero sin la penalización de almacenar 2 punteros en cada nodo .
template <typename T>
T* xor_ptrs(T* t1, T* t2)
{
return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(t1)^reinterpret_cast<uintptr_t>(t2));
}
uintptr_t
es un tipo entero sin signo que es capaz de almacenar un puntero. Lo que normalmente significa que es del mismo tamaño que un puntero.
Se define opcionalmente en C ++ 11 y estándares posteriores.
Una razón común para querer un tipo entero que pueda contener el tipo de puntero de una arquitectura es realizar operaciones específicas de un entero en un puntero, u ocultar el tipo de un puntero proporcionándolo como un "manejador" entero.
Edición: Tenga en cuenta que Steve Jessop tiene algunos detalles adicionales muy interesantes (que no robaré) en otra respuesta aquí para sus tipos pedantes :)