OVH Cloud OVH Cloud

Question sur les pointeurs restreints

32 réponses
Avatar
Taurre
Bonjour =E0 tous,

Je me suis r=E9cemment pench=E9 sur la notion de pointeurs restreints
introduite par la Norme C99 et il y a plusieurs questions auxquelles
je n'ai trouv=E9 aucune r=E9ponse:

- la premi=E8re porte sur ce code:

#include <stdlib.h>


void
test (int *a, int *b, int * restrict v)
{
*a =3D *v;
*b =3D *v;
}


int
main (void)
{
int a;
int b;
int v =3D 10;

test (&a, &b, &v);
return EXIT_SUCCESS;
}

si j'ai bien saisit la notion de pointeur restreint cela signifie,
dans le cas de la fonction "test", que l'objet sur lequel pointe la
variable "v" ne peut-=EAtre acc=E9der que via cette derni=E8re. Donc, en
toute logique, on peut supposer que l'objet point=E9 par la variable "v"
ne sera pas modifi=E9 lors de l'ex=E9cution de cette fonction. Or, si je
compile ce code, j'obtiens ces lignes en assembleur pour la fonction
"test":

movl (%rdx), %eax
movl %eax, (%rdi)
movl (%rdx), %eax
movl %eax, (%rsi)

la valeur de l'objet point=E9 par la variable "v" est charg=E9 deux fois
dans le registre eax alors qu'elle ne devrait l'=EAtre qu'une seule
fois... l'optimisation n'aura lieu que si un ou les deux autres
pointeurs sont =E9galement d=E9clar=E9 avec le qualificatif "restrict".
Quelqu'un pourrait-il m'expliquer pourquoi?

- la deuxi=E8me porte sur le m=EAme code, mais avec des variables de type
char. Dans cette hypoth=E8se, m=EAme si les trois pointeurs sont d=E9clar=
=E9s
avec le qualificatif "restrict", aucune optimisation n'est effectu=E9e
et j'obtiens donc:

movzbl (%rdx), %eax
movb %al, (%rdi)
movzbl (%rdx), %eax
movb %al, (%rsi)

Je pr=E9cise que je compile avec GCC et l'option d'optimisation -O2
Merci d'avance pour vos r=E9ponses.

2 réponses

1 2 3 4
Avatar
Taurre
On 8 juin, 20:52, Taurre wrote:
Après plusieurs relectures je pense avoir enfin compris le problème.
Si j'ai bien saisit, étant donné que les paramètres des fonctions s e
voient attribués les valeurs des expressions passées en arguments lor s
de l'appel, il se pose la question de savoir si, dans un tel cas, un
pointeur qui se voit assigner la même adresse qu'un pointeur restreint
peut être défini comme basé sur ce pointeur restreint. Les
développeurs de GCC ont décidé que oui et que, par conséquent, ce s
deux pointeurs s'alias. Il s'ensuit une absence d'optimisation pour
mon premier code (étant donné qu'il y a un doute).

@Pierre Habouzit: merci infiniment pour cette explication :)



En fouinant encore un peu sur Internet, je suis tombé sur ce lien:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_294.htm.
Il m'a pas mal éclairé sur le définition formelle du qualificatif
restrict.

Avec cela, je me rends compte que j'ai été cherché un peu (beaucoup)
trop loin, et que la réponse de Pierre Habouzit peut se résumer dans
cet exemple:

#include <stdlib.h>

int
main (void)
{
int a;
int * restrict p = &a;

{
int * restrict p1 = p;
int *p2 = p;

*p1 = *p2;
}

return EXIT_SUCCESS;
}

les pointeurs p1 et p2 sont basés sur le pointeur restreint p, mais p2
n'est pas basé sur p1. Par conséquent, il est tout à fait possible de
modifier l'objet pointé par p1 via p2 sans enfreindre la Norme (c'est
ce point que je n'avais pas compris, comme p1 et p2 ont la même
adresse il me semblait que p2 était basé sur p1).
Avatar
Taurre
En effet, si le standard impose qu'une lvalue accédant à un objet
pointé par un pointeur restreint soit dérivé de ce dernier, il
n'interdit en rien qu'une lvalue soit dérivée de plusieurs pointeurs
restreints. Ainsi, la lvalue *p1 est dérivée de p1, mais aussi de p.
De même, l'expression p2 est dérivée de p. Dès lors, il n'y a aucun e
violation du standard.
1 2 3 4