Il est probablement plus sûr, mais il ya quelques mises en garde.
Supposons que nous avons
T array[LEN];
Ensuite, &array
est de type T(*)[LEN]
.
Ensuite, &array + 1
est de nouveau de type T(*)[LEN]
, en pointant juste après la fin du tableau original.
Ensuite, *(&array + 1)
est de type T[LEN]
, qui peut être converti implicitement en T*
, continue de pointer juste après la fin du tableau original. (Si nous NE le déréférencement d'un emplacement de mémoire non valide: l' *
opérateur n'est pas évalué).
Ensuite, *(&array + 1) - 1
est de type T*
, pointant à la dernière matrice de localisation.
Enfin, nous déréférencement de cela (ce qui est légitime si la longueur du tableau n'est pas nul): *(*(&array + 1) - 1)
donne le dernier élément du tableau, une valeur de type T
.
Notez que la seule fois où nous avons fait de déréférencer un pointeur est dans cette dernière étape.
Maintenant, le potentiel des mises en garde.
Tout d'abord, *(&array + 1)
officiellement apparaît comme une tentative de déréférencer un pointeur qui pointe vers un emplacement de mémoire non valide. Mais il ne l'est pas vraiment. C'est la nature de la matrice de pointeurs: cette forme de déréférencement ne change que le type de l'indicateur, ne fait pas l'entraîner dans une tentative de récupérer la valeur de la position référencée. C'est, array
est de type T[LEN]
, mais il peut être implicitement converti en type &T
, pointant vers le premier élément du tableau; &array
est un pointeur de type T[LEN]
, pointant vers le début du tableau; *(&array+1)
est de nouveau de type T[LEN]
qui peut être implicitement converti en type &T
. À aucun moment, est un pointeur fait déréférencé.
Deuxièmement, &array + 1
peut en fait être une adresse non valide, mais il ne l'est pas vraiment: Mon C++11 manuel de référence me dit explicitement que "la Prise d'un pointeur vers l'élément d'un au-delà de la fin d'un tableau est garanti pour fonctionner", et une déclaration similaire est également faite dans le K&R, de sorte que je crois qu'il a toujours été la norme de comportement.
Enfin, dans le cas d'un zéro-longueur du tableau, l'expression déréférence l'emplacement de la mémoire juste avant le tableau, qui peut être non alloué/non valide. Mais cette question pourrait également se poser si on a utilisé une approche plus conventionnelle à l'aide de sizeof()
sans tester différente de zéro d'abord la longueur.
En bref, je ne crois pas qu'il y a quelque chose d'indéfini ou dépendant de l'implémentation à propos de cette expression du comportement.