Tant que votre type de structure n'a pas de rembourrage, il n'y a pas de soutien explicite dans la norme , mais le soutien à quelque chose de très proche peut être déduit.
Étant donné un type trivialement copiable T
, ce qui est autorisé explicitement est de copier sa représentation dans un tableau de char
(ou unsigned char
) et le dos.
Il n'est pas nécessaire que le contenu de la matrice soit conservé dans la matrice elle-même. Le contenu pourrait être stocké dans un fichier, et relu lors d'une exécution ultérieure du programme. Ou stocké dans un objet d'un type différent, aussi longtemps que ce type le permet. Pour que cela fonctionne, les implémentations doivent admettre des représentations memcpy
dans des objets lorsque ces représentations ne proviennent pas d'objets de type T
dans la même exécution.
En conséquence, à tout le moins,
int main() {
vec v = {1.9f, 2.5f, 3.1f};
float a[3];
assert(sizeof v == sizeof a);
{ char tmp[3 * sizeof(float)];
std::memcpy(tmp, &v, 3 * sizeof(float));
std::memcpy(a, tmp, 3 * sizeof(float)); }
assert(a[0] == v.x);
assert(a[1] == v.y);
assert(a[2] == v.z);
vec u;
{ char tmp[3 * sizeof(float)];
std::memcpy(tmp, a, 3 * sizeof(float));
std::memcpy(&u, tmp, 3 * sizeof(float)); }
assert(u.x == a[0]);
assert(u.y == a[1]);
assert(u.z == a[2]);
}
devrait soit échouer sur le premier assert
, ou passer. Pour toute représentation où il échouerait, il est trivial de créer une fonction qui arrive à produire cette représentation exacte de manière non ambiguë, donc elle ne doit pas échouer.
Maintenant, en omettant tmp
voici un peu incertain.
std::memcpy
est juste affectation répétée des octets individuels et aurait pu être explicitées. La sémantique de l'opérateur =
implique que pour les types trivialement copiables, a = b;
et { auto tmp = b; a = tmp; }
sont équivalents. Idem avec a = b; c = d;
et { auto tmp1 = b; auto tmp2 = d; a = tmp1; c = tmp2; }
, et ainsi de suite. Le premier est ce que fait un memcpy
, ce dernier est ce que deux memcpy
à travers tmp
faire. D'autre part, l'autorisation de copier dans et hors d'un tableau de char
peut être interprétée comme nécessitant un tableau réel de char
, et pas simplement l'équivalent fonctionnel de celui-ci. Personnellement, je ne m'inquiéterais probablement pas à moins que je ne découvre une implémentation qui utilise cette interprétation, mais si vous voulez jouer en toute sécurité, vous pouvez introduire un tel tableau temporaire, et vérifier que votre compilateur parvient à optimiser loin.
Relatif (ou peut-être en double): http://stackoverflow.com/questions/37211298/accessing-an-array-as-a-struct-vs-undefined-behavior – Barmar
@Barmar c'est le même problème discuté dans le question que j'ai liée. –
Ils disent tous les deux que c'est un comportement indéfini. Pourquoi pensez-vous que votre cas est différent? – Barmar