J'ai été en utilisant std::memcpy
de contourner stricte aliasing pendant une longue période.
Par exemple, l'inspection d'un float
, comme ceci:
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
Cependant, cette fois, j'ai vérifié la norme, je n'ai rien trouvé qui valide cette. Tout ce que je trouve est ceci:
Pour tout objet (autre que potentiellement-le chevauchement des sous-objet) de la trivialement copiable type T, si oui ou non l'objet titulaire d'un permis de valeur de type T, le sous-jacent octets ([intro.mémoire]) faisant l'objet peut être copié dans un tableau de char, unsigned char, ou std::byte ([cstddef.syn]).40 Si le contenu de ce tableau est copié en arrière dans l'objet, l'objet doit ensuite tenir sa valeur d'origine. [ Exemple:
#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
fin de l'exemple ]
et ce:
Pour toute trivialement copiable type T, si deux pointeurs vers T point distinct T des objets obj1 et obj2, où ni obj1 ni obj2 est potentiellement un chevauchement sous-objet, si le sous-jacent octets ([intro.mémoire]) qui obj1 sont copiés dans obj2,41 obj2 doit ensuite contenir la même valeur qu'obj1. [ Exemple:
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
fin de l'exemple ]
Donc, std::memcpy
ing float
/à partir de char[]
est autorisé, et std::memcpy
ing entre les mêmes trivial types est aussi permis.
C'est mon premier exemple (et le lien de réponse) bien définis? Ou de la bonne façon à examiner un float
est std::memcpy
en unsigned char[]
de la mémoire tampon, et l'aide d' shift
s et or
s pour construire un uint32_t
- il?
Remarque: en regardant std::memcpy
's garanties ne peuvent pas répondre à cette question. Pour autant que je sais, je pourrais remplacer std::memcpy
avec un simple octet-copie de la boucle, et la question sera la même.