4 votes

Pourquoi le pointage d'un élément avant le premier élément d'un tableau n'est-il pas autorisé en C ?

En C, un pointeur peut pointer vers n'importe quel élément d'un tableau, ainsi que vers un élément situé au-delà du dernier élément du tableau ; pointer au-delà est un comportement non défini (norme C11, §6.5.6, paragraphe 8).

Cependant, pourquoi le fait de pointer sur un élément avant le premier élément d'un tableau n'est-il pas autorisé de la même manière ?

P.S : Je sais que, pour contourner la restriction ci-dessus, on peut parfois déclarer un tableau plus grand d'une unité que nécessaire, puis n'utiliser que les positions à partir de 1 pour stocker les éléments, et enfin laisser la position 0 juste pour garantir que traverser le tableau en arrière sera sûr. Cependant, il arrive que l'on doive utiliser un tableau tel qu'il est donné, et alors le problème du pointage avant le premier élément demeure.

3voto

molbdnilo Points 9289

Je ne suis pas sûr que ce soit la logique, mais en pratique, il faudrait soit

  • supprimer les opérateurs relationnels sur les pointeurs (à cause du wraparound), ou bien
  • exiger qu'aucun objet de taille X ne soit stocké à une adresse inférieure à X, ou
  • couper la mémoire disponible en deux (à cause des adresses négatives).

Aucune des deux options n'est très agréable.

3voto

Stephan Lechner Points 29375

Le sujet "un pointeur est autorisé à pointer vers n'importe quel élément d'un tableau" fait partie du langage C depuis très longtemps ; on le trouve déjà dans le fichier Norme ANSI-C / C89 (cf. section 6.3.6 Opérateurs additifs, page 46f), qui mentionne déjà que dans cette plage, les implémentations doivent empêcher les débordements arithmétiques. Dans cette section, à la fin de la page 47, on peut également trouver une note de bas de page qui explique le raisonnement qui se cache derrière :

Une autre façon d'aborder l'arithmétique des pointeurs consiste à convertir d'abord l'élément pointeur(s) en pointeurs de caractères : Dans ce schéma, l'expression intégrale l'expression intégrale ajoutée ou soustraite du pointeur converti est d'abord multipliée par la taille de l'objet pointé à l'origine. est d'abord multipliée par la taille de l'objet pointé à l'origine et le et le pointeur résultant est reconverti dans le type original. Pour un pointeur soustraction, le résultat de la différence entre les pointeurs de caractères caractères est également divisé par la taille de l'objet pointé à l'origine. pointé à l'origine.

De ce point de vue, les implémentations ne doivent fournir qu'un seul élément supplémentaire. supplémentaire (qui peut chevaucher un autre objet du programme) juste après la l'objet afin de satisfaire l'exigence "un après le dernier élément". exigence .

Nous pouvons en déduire que la raison en est la prévention des débordements arithmétiques, qu'une mise en oeuvre debe éviter dans l'intervalle d'un tableau et d'un passé (mais qui évidemment n'a pas besoin d'être garantie pour un élément situé un avant le premier élément d'un tableau).

Pourquoi pas un avant - est probablement (je n'en ai pas la preuve) lié au fait que les plages de pointeurs pourraient être limitées à des segments de mémoire particuliers, et placer des objets au début d'un segment de mémoire avec une arithmétique comme "un avant le premier élément" pourrait conduire à un débordement. Je dirais que la déclaration "les implémentations doivent seulement fournir un octet supplémentaire (qui peut chevaucher un autre objet dans le programme) juste après la fin de l'objet" est un indicateur clair de cette hypothèse, car la norme de l'époque abordait explicitement le sujet d'"un octet supplémentaire" à la fin, mais ne proposait rien de similaire pour le début des segments de mémoire.

2voto

Lundin Points 21616

La raison pour laquelle il est permis de pointer au-delà du tableau en premier lieu, est de permettre certains types de modèles de programmation "C++/STL-ish" :

int array [n] = ...;
int* begin = array;
int* end = array + n;

for(int* i=begin; i!=end; i++)
...

Pour des situations comme celle ci-dessus, il est logique de pointer un élément au-delà du tableau. Mais bien sûr, il n'est pas logique d'accéder réellement à cet élément - ce qui serait un comportement indéfini.

Le cas ci-dessus est donc un cas particulier. Cependant, il n'existe aucune situation où il est logique d'indiquer un élément avant le tableau.

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