Una vez más: estricta regla de alias y char *
Cuanto más leo, más confundido me pongo.
La última pregunta de los relacionados es la más cercana a mi pregunta, pero me confundí con todas las palabras sobre la vida útil de los objetos y, especialmente, ¿está bien leer o no?
Para llegar directamente al punto. Corrígeme si estoy equivocado.
Esto está bien, gcc no da advertencia y estoy tratando de "leer el tipoT
(uint32_t
) a través dechar*
":
uint32_t num = 0x01020304;
char* buff = reinterpret_cast< char* >( &num );
Pero esto es "malo" (también da una advertencia) y estoy intentando "al revés":
char buff[ 4 ] = { 0x1, 0x2, 0x3, 0x4 };
uint32_t num = *reinterpret_cast< uint32_t* >( buff );
¿En qué se diferencia el segundo del primero, especialmente cuando hablamos de reordenar instrucciones (para la optimización)? Además, agregandoconst
No cambia la situación de ninguna manera.
¿O esto es solo una regla directa, que establece claramente: "esto se puede hacer en una dirección, pero no en la otra"? No pude encontrar nada relevante en los estándares (busqué esto especialmente en el estándar C ++ 11).
¿Es lo mismo para C y C ++ (mientras leo un comentario, lo que implica que es diferente para los 2 idiomas)?
solíaunion
para "solucionar" esto, que todavía parece serNO 100% correcto, ya que no está garantizado por el estándar (que establece que solo puedo confiar en el valor, que se modificó por última vez en elunion
)
Entonces, después de leermuchoAhora estoy más confundido. Solo supongomemcpy
Cuál es la "buena" solución?
Preguntas relacionadas:
¿Cuál es la estricta regla de alias?"Desreferenciar el puntero marcado con un tipo de letra romperá las reglas de alias estricto"¿Entiendo correctamente el alias estricto C / C ++?Regla de alias estricta y punteros 'char *'EDITAR
La situación del mundo real: tengo una biblioteca de terceros (http://www.fastcrypto.org/), que calcula UMAC y el valor devuelto está enchar[ 4 ]
. Entonces necesito convertir esto auint32_t
. Y, por cierto, la lib usa cosas como((UINT32 *)pc->nonce)[0] = ((UINT32 *)nonce)[0]
mucho. De todas formas.
Además, estoy preguntando qué está bien y qué está mal y por qué. No solo sobre el reordenamiento, la optimización, etc. (lo interesante es que con-O0
no hay advertencias, solo con-O2
)
Y tenga en cuenta: Soy consciente de la situación endian grande / pequeña. No es el caso aquí. Realmente quiero ignorar el endianness aquí. Las "reglas estrictas de alias" suenan como algo realmente serio, mucho más serio que la endianidad equivocada. Quiero decir, como acceder / modificar la memoria, que no se debe tocar;alguna tipo de UB en absoluto.
Citas de los estándares (C y C ++) sería muy apreciado. No pude encontrar nada sobre las reglas de alias ni nada relevante.