La confusion est que C permet explicitement de type beaucoup les jeux de mots par l'intermédiaire d'un syndicat, alors que C++ (c++11) n'a pas une telle autorisation.
c11
6.5.2.3 de la Structure et des membres de l'union
95) Si le membre a utilisé pour lire le contenu d'une union de l'objet n'est pas le même que le membre de la dernière
de stocker une valeur dans l'objet, la partie appropriée de l'objet de la représentation de la valeur, est réinterprétée
comme un objet de représentation dans le nouveau type décrit dans 6.2.6 (un processus parfois appelé ‘type
beaucoup les jeux de mots"). Cela pourrait être un piège de la représentation.
La situation avec C++:
c++11
9.5 Syndicats [classe.l'union]
Dans un syndicat, au plus l'un des non-membres de données statiques peut être actif à tout moment, c'est la valeur de la
plus l'un des non-membres de données statiques peuvent être stockées dans une union à tout moment.
C++ plus tard a la langue qui permet l'utilisation de syndicats contenant struct
s avec la commune de séquences initiales; ce n'est cependant pas permis de type beaucoup les jeux de mots.
Pour déterminer si le type d'union-beaucoup les jeux de mots est autorisé en C++, nous avons cherché plus loin. Rappelons que le c99 est une référence normative pour le C++11 (et C99 a similaires la langue de C11 permettant à l'union de type beaucoup les jeux de mots):
3.9 Types [de base.types]
4 - L'objet de la représentation d'un objet de type T est la séquence de N unsigned char objets pris par
l'objet de type T, où N est égal à sizeof(T). La valeur de la représentation d'un objet est l'ensemble de bits
la valeur de type T. Pour trivialement copiable types, la valeur de la représentation est un ensemble de bits dans l'objet
la représentation qui détermine une valeur, qui est un élément discret de la mise en œuvre définies par l'ensemble de
des valeurs. 42
42) L'intention est que le modèle de mémoire de C++ est compatible avec celui de la norme ISO/IEC 9899 Langage de Programmation C.
Il devient particulièrement intéressant lorsque nous lisons
3.8 durée de vie des Objets [de base.la vie]
La durée de vie d'un objet de type T commence lorsque:
- stockage avec le bon alignement et la taille pour le type T est obtenu, et
- si l'objet est non-trivial d'initialisation, de son initialisation est terminée.
Donc, pour un type primitif (ce qui , ipso facto, a trivial d'initialisation) contenus dans une union, la durée de vie de l'objet couvre au moins la durée de vie de l'union elle-même. Cela nous permet d'invoquer
3.9.2 les types Composés [de base.composé]
Si un objet de type T est situé à une adresse à l'Un, un pointeur de type cv T* dont la valeur est la
adresse A est le point de l'objet, indépendamment de la façon dont la valeur a été obtenue.
En supposant que l'opération qui nous intéresse est de type beaucoup les jeux de mots c'est à dire en prenant la valeur de un non-actif membre de l'union, et vu ci-dessus que nous avons une référence valide à l'objet visé par ce membre, cette opération est lvalue-à-rvalue de conversion:
4.1 Lvalue-à-rvalue de conversion [conv.lval]
Un glvalue d'un non-fonctionnement, à la non-type de tableau T
peut être converti en prvalue.
Si T
est un type incomplète, un programme qui nécessite cette conversion est mal formé. Si l'objet pour lequel la glvalue se réfère n'est pas un objet de type T
et n'est pas un objet d'un type dérivé de T
, ou si l'objet est non initialisée, un programme qui nécessite cette conversion a un comportement indéfini.
La question est alors de savoir si un objet qui est un non-actif membre de l'union est initialisé par le stockage de l'actif membre de l'union. Aussi loin que je peux dire, ce n'est pas le cas et si bien que si:
- un syndicat est copié en
char
de la matrice de stockage et à l'arrière (3.9:2), ou
- un syndicat est bytewise copié à l'autre de l'union du même type (3.9:3), ou
- un syndicat est accessible à travers les limites du langage par un élément de programme conforme à la norme ISO/IEC 9899 (comme défini) (3.9:4 note 42), puis
l'accès à une union par un non-membre actif est défini et est défini de manière à suivre l'objet et la valeur de la représentation, de l'accès sans que l'un des ci-dessus interpositions est un comportement indéterminé. Ceci a des implications pour les optimisations autorisées à être exécutées sur un tel programme, comme la mise en œuvre peut bien sûr supposer que les comportements indéfinis ne se produit pas.
Bien que l'on peut légitimement forme une lvalue à un non-actif membre de l'union (c'est pourquoi l'affectation à un non-membre actif sans la construction est ok), il est considéré comme non initialisée.