Quiero realizar un control para la alineación de memoria de algún tipo T
. La forma más sencilla de hacer esto esuintptr_t alternativa portátil
if (((uintptr_t)&var & __alignof(T) - 1) == 0) ...
embargo
, uintptr_t
no es parte de la existente C++ estándar y no es compatible con algunos compiladores, así que estoy buscando una manera alternativa portátil para hacer esto y std::ptrdiff_t
se ve bien para mi. std::ptrdiff_t
garantizado para poder almacenar la diferencia entre dos punteros, pero ¿quién dice que uno de esos punteros no puede ser un puntero nulo? En ese caso, std::ptrdiff_t
debe tener al menos el mismo tamaño que el puntero.
template <typename T> bool is_properly_aligned(const T* const ptr)
{
std::ptrdiff_t diff = (ptr - static_cast<T*>(0)) * sizeof(T);
return ((diff & __alignof(T) - 1) == 0);
}
o así (para deshacerse de la multiplicación por sizeof(T)
)
template <typename T> bool is_properly_aligned(const T* const ptr)
{
std::ptrdiff_t diff =
reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);
return ((diff & __alignof(T) - 1) == 0);
}
¿Qué piensa acerca de este tipo de solución? ¿Es lo suficientemente portátil? No veo ninguna razón por la cual esto debería fallar, sin embargo, me gustaría confirmarlo.
Gracias.
Usted escribió 'Creo que ptrdiff_t es de hecho el tipo de datos correcto para representar la diferencia entre dos punteros'. Mi pregunta es, ¿qué piensas, es portátil almacenar la representación de entero de puntero en ptrdiff_t? – ledokol
Usted escribió 'pero tiene muy poco sentido comparar dos punteros si no apuntan a un bloque de memoria contigua que proviene de una asignación simple'. No estoy comparando, estoy calculando la distancia y el propósito de esto es obtener una representación entera del puntero. – ledokol
Pero ptrdiff_t no es un tipo numérico como int. Ni siquiera está garantizado que tenga el mismo tamaño que int (y en los sistemas de 64 bits, generalmente no lo es). Si quieres jugar así, también puedes lanzar (int) ptr y verificar los bits más bajos para alinear. – Enno