J'ai utilisé les syndicats plus tôt confortablement; aujourd'hui, j'ai été alarmé en lisant cet article et j'ai appris que ce code
union ARGB
{
uint32_t colour;
struct componentsTag
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} components;
} pixel;
pixel.colour = 0xff040201; // ARGB::colour is the active member from now on
// somewhere down the line, without any edit to pixel
if(pixel.components.a) // accessing the non-active member ARGB::components
est en fait un comportement indéfini, c'est-à-dire que la lecture d'un membre de l'union autre que celui écrit récemment conduit à un comportement indéfini. Si ce n'est pas l'usage prévu des syndicats, c'est quoi? Quelqu'un peut-il l'expliquer de manière détaillée?
Mettre à jour:
Je voulais clarifier certaines choses avec le recul.
- La réponse à la question n'est pas la même pour C et C ++; mon jeune ignorant l'a étiqueté à la fois comme C et C ++.
- Après avoir parcouru la norme C ++ 11, je ne pouvais pas dire de façon concluante qu'elle appelle l'accès / l'inspection d'un membre d'union non actif est indéfini / non spécifié / défini par la mise en œuvre. Tout ce que j'ai pu trouver était le §9.5 / 1:
Si une union de mise en page standard contient plusieurs structures de mise en page standard qui partagent une séquence initiale commune, et si un objet de ce type d'union de mise en page standard contient l'une des structures de mise en page standard, il est autorisé d'inspecter la séquence initiale commune de tout des membres de structure de mise en page standard. §9.2 / 19: Deux structures de mise en page standard partagent une séquence initiale commune si les membres correspondants ont des types compatibles avec la mise en page et qu'aucun des membres n'est un champ de bits ou les deux sont des champs de bits de même largeur pour une séquence d'une ou plusieurs initiales membres.
- En C (à partir de C99 TC3 - DR 283 ), il est légal de le faire ( merci à Pascal Cuoq de l'avoir soulevé). Cependant, tenter de le faire peut toujours conduire à un comportement indéfini , si la valeur lue s'avère non valide (appelée "représentation d'interruption") pour le type par lequel elle est lue. Sinon, la valeur lue est définie par l'implémentation.
C89 / 90 a appelé cela sous un comportement non spécifié (Annexe J) et le livre de K&R dit que sa mise en œuvre est définie. Citation de K&R:
C'est le but d'une union - une variable unique qui peut légitimement contenir l'un de plusieurs types. [...] tant que l'utilisation est cohérente: le type récupéré doit être le type le plus récemment stocké. Il est de la responsabilité du programmeur de garder une trace du type qui est actuellement stocké dans une union; les résultats dépendent de l'implémentation si quelque chose est stocké sous un type et extrait sous un autre.
Extrait du TC ++ PL de Stroustrup (accent sur le mien)
L'utilisation d'unions peut être essentielle pour la compatibilité des données [...] parfois mal utilisées pour la "conversion de type ".
Surtout, cette question (dont le titre reste inchangé depuis ma demande) a été posée dans le but de comprendre le but des unions ET non sur ce que la norme autorise . ce n'était pas le but ou l'intention initiale d'introduire l'héritage en tant que fonctionnalité du langage C ++ . C'est la raison pour laquelle la réponse d'Andrey reste celle acceptée.
scouring C++11's standard I couldn't conclusively say that it calls out accessing/inspecting a non-active union member is undefined [...] All I could find was §9.5/1
...vraiment? vous citez une note d' exception , pas le point principal au début du paragraphe : "Dans une union, au plus l'un des membres de données non statiques peut être actif à tout moment, c'est-à-dire la valeur d'au plus l'un des les membres de données non statiques peuvent être stockés dans une union à tout moment. " - et jusqu'à p4: "En général, il faut utiliser des appels de destructeur explicites et placer de nouveaux opérateurs pour changer le membre actif d'une union "
b, g, r,
eta
peut ne pas être contiguë, et donc ne pas correspondre à la disposition d'unuint32_t
. Cela s'ajoute aux problèmes d'endianisme que d'autres ont signalés.