Is std :: memcpy entre diferentes tipos trivialmente copiables comportamiento indefinido?
He estado usandostd::memcpy
evitar aliasing estricto por mucho tiempo
Por ejemplo, inspeccionar unfloat
, me gustaest:
float f = ...;
uint32_t i;
static_assert(sizeof(f)==sizeof(i));
std::memcpy(&i, &f, sizeof(i));
// use i to extract f's sign, exponent & significand
Sin embargo, esta vez, he verificado el estándar, no he encontrado nada que valide esto. Todo lo que encontré esest:
Para cualquier objeto (que no sea un subobjeto potencialmente superpuesto) de tipo T copiable trivialmente, ya sea que el objeto tenga o no un valor válido de tipo T, los bytes subyacentes ([intro.memory]) que componen el objeto se pueden copiar en una matriz de char, unsigned char o std :: byte ([cstddef.syn]). 40 Si el contenido de esa matriz se copia nuevamente en el objeto, el objeto mantendrá posteriormente su valor original. [Ejemplo:
#define N sizeof(T)
char buf[N];
T obj; // obj initialized to its original value
std::memcpy(buf, &obj, N); // between these two calls to std::memcpy, obj might be modified
std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type holds its original value
- ejemplo final]
yest:
Para cualquier tipo T trivialmente copiable, si dos punteros a T apuntan a objetos T distintos obj1 y obj2, donde ni obj1 ni obj2 es un subobjeto potencialmente superpuesto, si los bytes subyacentes ([intro.memory]) que componen obj1 se copian en obj2, 41 obj2 posteriormente tendrá el mismo valor que obj1. [Ejemplo:
T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of trivially copyable type in *t1p contains
// the same value as the corresponding subobject in *t2p
- ejemplo final]
Asi que,std::memcpy
ing afloat
a / desdechar[]
está permitido ystd::memcpy
ing entre los mismos tipos triviales también está permitido.
¿Está bien definido mi primer ejemplo (y la respuesta vinculada)? O la forma correcta de inspeccionar unafloat
Es parastd::memcpy
en ununsigned char[]
buffer, y usandoshift
s yor
s para construir unauint32_t
¿de eso
Nota: mirando astd::memcpy
as garantías de @ pueden no responder esta pregunta. Que yo sepa, podría reemplazarstd::memcpy
con un bucle simple de byte-copy, y la pregunta será la misma.