Départ avec votre exemple:
int strict_aliasing_example(int *i, float *f)
{
*i = 1;
*f = 1.0;
return (*i);
}
Nous allons d'abord reconnaître que, en l'absence de syndicats, ce serait violer le strict aliasing règle s' i
et f
pointent vers le même objet; en supposant que l'objet n'est pas efficace, alors *i = 1
jeux de l'effectif type d' int
et *f = 1.0
lui float
, et la finale, return (*i)
puis accède à un objet avec efficace d' float
via une lvalue de type int
, ce qui est clairement interdit.
La question est de savoir si cela serait tout de même montant à un strict-aliasing violation si les deux i
et f
point pour les membres de la même union. Sur membre de l'union de l'accès via le "." l'accès des membres de l'opérateur, la spécification dit (6.5.2.3):
Un postfix expression suivie par la . opérateur et un identifiant
désigne un membre d'une structure ou d'une union de l'objet. La valeur, c'est que
de la de membres nommés (95) et est une lvalue si la première expression est
une lvalue.
La note de bas de page 95 visées ci-dessus, dit:
Si le membre utilisé pour lire le contenu d'une union de l'objet n'est pas la
même en tant que membre de la dernière utilisée pour stocker une valeur dans l'objet, le
partie appropriée de l'objet de la représentation de la valeur est
réinterprété 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.
C'est clairement destiné à permettre le type de beaucoup les jeux de mots par l'intermédiaire d'un syndicat, mais il convient de noter que (1) notes de bas de page sont non-normative, qui est, ils ne sont pas censés proscrire les comportements, mais ils devraient clarifier l'intention d'une partie du texte en accord avec le reste de la spécification, et (2) cette provision pour type beaucoup les jeux de mots par l'intermédiaire d'un syndicat est réputé par les éditeurs de compilateurs comme s'appliquant uniquement pour l'accès par les membres de l'union opérateur d'accès - depuis stricte ailleurs aliasing est assez vide de sens, depuis à peu près tout potentiellement aliasing accède pourrait également être potentiellement membres de la même union.
Votre exemple les magasins via un pointeur vers un non-existant ou au moins non-actif membre de l'union, et ce qui, soit s'engage à une stricte aliasing violation (puisqu'il accède au membre qui est active à l'aide d'une lvalue de inadaptés type) ou utilise une lvalue qui ne désigne pas un objet (puisque l'objet correspondant à la non-membre actif n'existe pas) - il pourrait être soutenu de toute façon, et que la norme n'est pas particulièrement clair, mais de toute interprétation signifie que votre exemple a un comportement indéterminé.
(J'ajoute que je ne vois pas comment la note de bas de page permettant de type beaucoup les jeux de mots par l'intermédiaire d'un syndicat décrit le comportement qui est contraire inhérente dans le cahier des charges - qui est, il semble casser l'ISO règle de ne pas prescrire des comportements; rien d'autre dans le cahier des charges semble faire toute provision pour le type de beaucoup les jeux de mots par l'intermédiaire d'un syndicat. En outre, il est quelque chose d'un tronçon de lire le texte normatif comme exigeant que cette forme de type beaucoup les jeux de mots exige que l'accès doit être faite immédiatement par le type d'union).
Il y a souvent confusion causée par une autre partie de la spécification, toutefois, également en 6.5.2.3:
Une garantie spéciale est faite dans le but de simplifier l'utilisation des syndicats:
si une union contient plusieurs structures qui partagent un tronc commun initial
la séquence (voir ci-dessous), et si l'objet contient actuellement un
de ces structures, il est autorisé à inspecter la commune initiale
une partie de l'un d'eux partout où une déclaration de l'achèvement de type
de l'union est visible.
Bien que cela ne s'applique pas à votre exemple, car il n'y a pas de commune de la séquence initiale, j'ai vu des gens lisent cela comme une règle générale régissant le type de beaucoup les jeux de mots (au moins quand une séquence initiale est impliqué); ils croient qu'il implique qu'il doit être possible d'utiliser ce type beaucoup les jeux de mots à l'aide de deux pointeurs vers les différents membres de l'union chaque fois que l'union complète la déclaration est visible (car des mots à cet effet apparaître dans le paragraphe cité ci-dessus). Cependant, je tiens à souligner que le paragraphe ci-dessus ne s'applique que pour les membres de l'union de l'accès via l'opérateur".". Le problème avec les concilier cette compréhension est, dans ce cas, la déclaration de l'union doit de toute façon être visible, car sinon vous ne seriez pas en mesure de consulter les membres de l'union. Je pense que c'est cette erreur dans le libellé, combinée avec la même mauvaise formulation de l'Exemple 3 (La suivante n'est pas valide fragment (parce que le type d'union n'est pas visible ...), lors de l'union, la visibilité n'est pas vraiment le facteur décisif), qui fait que certaines personnes de l'interpréter, que la commune de la-première-séquence exception est destiné à s'appliquer à l'échelle mondiale, et pas seulement pour l'accès des membres via l'opérateur".", comme une exception à la stricte aliasing règle; et, étant parvenu à cette conclusion, un lecteur pourrait alors interpréter la note de bas de page concernant le type de beaucoup les jeux de mots à appliquer à l'échelle mondiale également, et certains le font: voir la discussion sur ce bug de GCC par exemple (à noter que le bug a été dans l'état SUSPENDU pour une longue période).
(D'ailleurs, je suis conscient de plusieurs compilateurs qui ne mettent pas en œuvre le "bien commun global initial de la séquence de" la règle. Je ne suis pas spécialement au courant de tout les compilateurs qui mettent en œuvre le "bien commun global initial de la séquence de la" règle pas tout en permettant aussi de type arbitraire beaucoup les jeux de mots, mais cela ne signifie pas que ces compilateurs n'existent pas. Le comité de la réponse au Rapport de Défaut 257 suggère qu'ils ont l'intention de la règle globale, cependant, personnellement, je pense que l'idée que la simple visibilité d'un type qui devrait changer la sémantique de code qui ne fait pas référence à ce type est profondément erronée, et je sais que les autres sont d'accord).
À ce stade, vous pourriez poser la question de comment la lecture d'un non-actif membre de l'union par les états-opérateur d'accès ne viole pas les strictes de l'aliasing, si faire de même via un pointeur de fait. C'est encore un domaine où le cahier des charges est un peu floue, la clé est peut-être dans le choix des lvalue est responsable de l'accès. Par exemple, si un syndicat d'objet u
a un membre de l' a
et je l'ai lu via l'expression u.a
, alors on pourrait interpréter cela comme un accès de l'objet membre (a
) ou simplement comme un accès de l'union de l'objet (u
) que le membre de la valeur est ensuite extrait à partir de. Dans ce dernier cas, il n'y a pas d'aliasing violation, car il est spécifiquement autorisé à accéder à un objet (c'est à dire le membre actif de l'objet) par l'intermédiaire d'une lvalue de type d'agrégat contenant approprié membre (6.5¶7). En effet, la définition de l'opérateur d'accès au membre dans 6.5.2.3 ne l'appui de cette interprétation, si peu faiblement: la valeur correspond à celle de l'nommé membre - alors qu'il est potentiellement une lvalue, il n'est pas nécessaire pour accéder à l'objet visé par cette lvalue afin d'obtenir la valeur du membre, et ainsi de stricte aliasing violation est évité. Mais c'est encore une fois étirant un peu.
(Pour moi, il semble sous-spécifiée, généralement, quand un objet a "sa valeur stockée et accessible ... par une lvalue expression" conformément à 6.5¶7; on peut bien sûr prendre une décision raisonnable, pour nous-mêmes, mais nous devons être prudents pour permettre de beaucoup les jeux de mots par les syndicats comme indiqué ci-dessus, ou autrement être prêt à ignorer note de bas de page 95. Malgré la verbiage inutile, le cahier des charges qui manque parfois dans les détails nécessaires).
Arguments au sujet de l'union de la sémantique, invariablement, reportez-vous à la RD 236 à un certain point. En effet, votre code d'exemple est superficiellement très similaire au code dans ce Rapport de Défaut. Je tiens à préciser que:
- "Le comité estime que l'Exemple 2 viole l'aliasing règles de 6,5 paragraphe 7" - ce n'est pas en contradiction avec mon raisonnement ci-dessus;
- "Afin de ne pas enfreindre les règles, la fonction f dans l'exemple devrait être écrit" - ce qui appuie mon raisonnement ci-dessus; vous devez utiliser de l'union de l'objet (et de l'opérateur".") pour changer de type de membre, sinon, vous accédez à un inexistante membre (depuis l'union peut contenir qu'un seul membre à la fois);
- L'exemple de la RD 236 est pas sur le type-beaucoup les jeux de mots. C'est sur si c'est ok pour l'attribuer à un non-actif membre de l'union par l'intermédiaire d'un pointeur à ce membre. Le code en question est subtilement différent de ce qui est en question ici, puisqu'il ne tente pas d'accéder à l ' "original" membre de l'union de nouveau après avoir écrit pour le second membre. Ainsi, en dépit de la similitude structurelle dans le code d'exemple, le Rapport de Défaut est largement indépendantes de votre question.
- Le Comité de la Réponse de la RD 236 affirme que "les Deux programmes invoquer un comportement indéfini". Ce n'est cependant pas pris en charge par la discussion, ce qui montre que l'Exemple 2 invoque un comportement indéterminé. Je crois que la réponse est erronée.