6 votes

La relation d'égalité des pointeurs après la conversion aller-retour est-elle garantie comme étant transitive ?

Cette question est similaire à " Tous les pointeurs sont-ils assurés de passer correctement par void * ? "mais un peu plus profond.

Compte tenu de ce qui précède :

#include <stdint.h>

int i;
int *ip1 = &i;
void *vp1 = ip1;
intptr_t x = (intptr_t)vp1;
void *vp2 = (void *)x;
int *ip2 = vp2;

puis vp1 == vp2 est garanti vrai (même s'ils ne partagent pas la même représentation binaire), mais est ip1 == ip2 garantie de vérité ? La relation d'égalité est-elle transitive dans ce cas ?

6voto

dbush Points 8590

Cette conversion est garantie.

Tout d'abord, la conversion d'un pointeur d'objet en un void * est décrite au point 6.3.2.3p1 de l'annexe I. C standard :

Un pointeur sur void peut être converti en ou à partir d'un pointeur sur n'importe quel type d'objet. Un pointeur sur n'importe quel type d'objet peut être converti en un pointeur sur void et inversement ; le résultat doit être être égal au pointeur d'origine

Deuxièmement, la conversion d'un void * à un intptr_t et le retour sont décrits au point 7.20.1.4p1 :

Le type suivant désigne un type d'entier signé avec l'attribut propriété selon laquelle tout pointeur valide vers void peut être converti en ce type, puis reconverti en pointeur de void et le le résultat sera égal au pointeur d'origine :

intptr_t

Le type suivant désigne un type d'entier non signé avec la propriété que tout pointeur valide vers void peut être converti en ce type, puis reconverti en pointeur de void et le le résultat sera égal au pointeur d'origine :

uintptr_t

Ces types sont facultatifs.

Dans ce cas, un int * ( ip1 ) est converti en void * ( vp1 ), et le void * à un intptr_t .

En intptr_t est reconverti en void * ( vp2 ). Par 7.20.1.4p1, vp2 doit être égal à vp1 .

Dans ce cas vp2 est converti en un int * ( ip2 ). Puisque vp2 est identique à vp1 , la conversion de vp2 a int * équivaut à convertir le vp1 a int * et donnera donc un pointeur dont la comparaison sera égale à ip1 conformément au 6.3.2.3p1.

5voto

Eric Postpischil Points 36641

La transitivité de l'égalité pour les pointeurs, quelle que soit leur provenance, découle de la spécification des opérateurs d'égalité. C 2018 6.5.9 6 dit :

Deux pointeurs sont égaux si et seulement s'ils sont tous deux des pointeurs nuls, s'ils sont tous deux des pointeurs vers le même objet (y compris un pointeur vers un objet et un sous-objet à son début) ou la même fonction, s'ils sont tous deux des pointeurs vers un élément après le dernier élément du même tableau, ou si l'un est un pointeur vers un élément après la fin d'un tableau et l'autre est un pointeur vers le début d'un tableau différent qui suit immédiatement le premier tableau dans l'espace d'adressage.

Les pointeurs nuls et les pointeurs de fonctions ne sont pas pris en compte ici, étant donné que a == b y b == c s'évaluent comme vraies, elles doivent satisfaire à l'une des conditions énumérées dans la spécification, et nous avons donc ces cas :

Données a == b .

Données b == c .

a == c ?

a y b les deux pointent vers le même objet .

b y c pointent tous deux vers le même objet.

a y c Les deux indiquent le même objet. C'est pourquoi a == c est évaluée comme étant vraie.

a y b pointent tous deux vers le même objet.

c pointe sur l'avant-dernier élément d'un tableau et b pointe vers le début d'un tableau qui le suit.

c pointe sur l'avant-dernier élément d'un tableau et a pointe vers le début d'un tableau qui le suit. C'est pourquoi a == c est évaluée comme étant vraie.

a y b pointent tous deux vers l'avant-dernier élément du même tableau.

b y c pointent tous deux vers l'avant-dernier élément du même tableau.

a y c pointent tous deux vers l'avant-dernier élément du même tableau. C'est pourquoi a == c est évaluée comme étant vraie.

a pointe sur l'avant-dernier élément d'un tableau et b pointe vers le début d'un objet de type tableau qui le suit.

b y c pointent tous deux vers le même objet.

a pointe sur l'avant-dernier élément d'un tableau et c pointe vers le début d'un objet de type tableau qui le suit. C'est pourquoi a == c est évaluée comme étant vraie.

b pointe sur l'avant-dernier élément d'un tableau et a pointe vers le début d'un objet de type tableau qui le suit.

b y c pointent tous deux vers l'avant-dernier élément d'un tableau.

c pointe sur l'avant-dernier élément d'un tableau et a pointe vers le début d'un objet de type tableau qui le suit. C'est pourquoi a == c est évaluée comme étant vraie.

Notez qu'il n'y a pas de cas où b pointe sur un objet de la première colonne et sur l'avant-dernier élément d'un tableau de la deuxième colonne, ou vice-versa : quel que soit le type de pointeur, il doit être du même type en a == b y b == c .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X