== pour la comparaison de pointeur

Je cite le “Langage de programmation C” de Kernighan & Ritchie:

Tout pointeur peut être comparé de manière significative pour l’égalité ou l’inégalité à zéro. Mais le comportement n’est pas défini pour l’arithmétique ou les comparaisons avec des pointeurs qui ne pointent pas vers des membres du même tableau. (Il existe une exception: l’adresse du premier élément après la fin d’un tableau peut être utilisée dans l’arithmétique de pointeur.)

Est-ce que cela signifie que je ne peux pas compter sur == pour vérifier l’égalité de pointeurs différents? Dans quelles situations cette comparaison conduit-elle à un résultat erroné?

Un exemple qui me vient à l’esprit est l’architecture de Harvard avec des espaces d’adresse séparés pour le code et pour les données. Sur les ordinateurs de cette architecture, le compilateur peut stocker des données constantes dans la mémoire de code. Puisque les deux espaces d’adresses sont séparés, un pointeur sur une adresse de la mémoire de code pourrait être numériquement égal à un pointeur de la mémoire de données, sans pointer vers la même adresse.

L’opérateur d’égalité est défini pour tous les pointeurs valides et le seul moment où il peut donner un “faux positif” est lorsqu’un pointeur pointe vers un élément après la fin d’un tableau et que l’autre arrive à un point (ou à des points grâce à définition de structure) vers un autre object stocké juste en dehors du tableau en mémoire.

Je pense que votre erreur traite K & R comme normatif. Voir le standard C99 (belle version html ici: http://port70.net/~nsz/c/c99/n1256.html ), 6.5.9 sur l’opérateur d’égalité. Le problème des comparaisons non définies ne concerne que les opérateurs relationnels (voir 6.5.8):

Lorsque deux pointeurs sont comparés, le résultat dépend des emplacements relatifs dans l’espace d’adressage des objects pointés. Si deux pointeurs sur des types d’object ou des types incomplets pointent tous deux sur le même object ou tous les deux, un après le dernier élément du même object tableau, ils se comparent égaux. Si les objects pointés sont des membres du même object agrégé, les pointeurs sur les membres de la structure déclarés ultérieurement comparent les pointeurs supérieurs aux membres déclarés précédemment dans la structure, et les pointeurs sur des éléments de tableau avec des valeurs en indice plus grandes comparent les pointeurs supérieurs aux éléments du même tableau. avec des valeurs plus faibles en indice. Tous les pointeurs vers les membres d’un même object d’union se comparent. Si l’expression P pointe sur un élément d’un object tableau et que l’expression Q pointe sur le dernier élément du même object tableau, l’expression du pointeur Q + 1 est supérieure à P. Dans tous les autres cas, le comportement est indéfini.

J’interprète ceci comme suit:

 short a[9]; int b[12]; short * c = a + 9; 

Ici, il est valide de dire que

 c > a 

parce que c résulte d’ a arithmétique de pointeur de via,

mais pas nécessairement que

 b == c 

ou

 c <= b 

ou quelque chose de similaire, car ils résultent de tableaux différents, dont l'ordre et l'alignement en mémoire ne sont pas définis.

Vous ne pouvez pas utiliser la comparaison de pointeur pour comparer des pointeurs pointant dans des tableaux différents.

Alors:

int arr[5] = {1, 2, 3, 4, 5};

int * p = &arr[0];

int anotherarr[] = {1, 2};

int * pf = &anotherarr[0];

Vous ne pouvez pas faire if (p == pf) car p et pf ne pointent pas dans le même tableau. Cela conduira à un comportement indéfini.

Vous pouvez compter sur la comparaison de pointeurs s’ils pointent dans le même tableau.

Pas sûr du cas arithmétique moi-même.

Vous pouvez faire == et != Avec des pointeurs de différents tableaux.

<, <=,>,> = n’est pas défini.