Lorsque vous utilisez un pointeur en C restreindre, est-il OK pour changer une variable en utilisant son identificateur initial?

StackOverflow https://stackoverflow.com/questions/3936060

  •  30-09-2019
  •  | 
  •  

Question

Lorsque vous utilisez un pointeur restrict en C, est-il OK pour changer la variable en utilisant son premier Identifier ? Par exemple:

int foo = 0;

int * restrict fooPtr = &foo;
++(*fooPtr);                   // Part 1: foo is 1 (OK)

++foo;                         // Part 2: foo is 2 (Is this OK?)

int * fooPtr2 = &foo;
++(*fooPtr2);                  // Part 3: foo is 3 (BAD: You shouldn't access via a second pointer)

... Je change la valeur de foo à foo après la restrict fooPtr a été créé.

Partie 1 semble OK pour moi. Je suis confus au sujet de Partie 2 . Et d'après ce que je comprends restrict, Partie 3 est mauvais (compilateur le permet, mais son comportement est indéfini, et il est au programmeur de ne pas le faire).

Était-ce utile?

La solution

Non, Partie 2 n'est pas OK.

La partie spécifique de la norme est 6.7.3.1/4. Cette section est assez dense, et prend quelques relectures, mais P est un pointeur restreindre, et X est un objet, il permet d'accéder, et qui est modifié. Donc, dans votre exemple P est fooPtr et X est foo. Puis:

  

Toutes les autres lvalue utilisé pour accéder à la   la valeur de X est également son adresse   sur la base de P.

« sur la base » est défini dans le paragraphe précédent, et pour résumer, le foo lvalue fait pas ont son adresse sur la base du pointeur P. Donc restreindre la règle est rompue lorsque vous accédez à l'objet foo par son propre nom.

Partie 3 n'est pas OK pour exactement la même raison, le *fooPtr2 lvalue ne repose pas sur P non plus, mais il est également utilisé pour l'accès X.

Je dis « pas OK » - pour être précis, la combinaison de 1 + 2 provoque le comportement non défini, comme le fait la combinaison de 1 + 3. Tant que vous ne lisez pas réellement l'objet par le pointeur de restreindre, aucune de la définition de « limiter les coups de pied dans ». Si vous vouliez vous pouvez supprimer la partie 1, conserver le pointeur restreindre utilisé, puis 2 et 3 serait OK.

Autres conseils

Oui, est un comportement non défini "partie 3". De l'C99 (6.7.3, paragraphe 7):

  

Un objet qui est accessible par un   restreindre quali fi é pointeur a une   association spéciale avec ce pointeur.   Cette association, définie en 6.7.3.1   ci-dessous, exige que tous les accès à   que l'utilisation de l'objet, directement ou   indirectement, la valeur de cette   pointeur particulier.

Je dirais que # 2 est mauvais. Par exemple, le compilateur peut optimiser en chargeant la valeur à * fooPtr dans un registre, puis écrire que de retour de valeur du registre vers foo plus tard - après votre ++ foo, de sorte que le ++ foo est perdu.

En supposant que toutes les parties de votre question se produisent dans le même bloc, ce n'est pas OK pour accéder à la valeur directement foo (partie 2) ni d'y accéder via un autre pointeur (partie 3):

  • 6.7.3.1 Définition formelle de restreindre
  

Toutes les autres lvalue utilisé pour accéder à la valeur de X doit aussi avoir son adresse basée sur P.

La définition formelle de restrict est assez difficile à suivre (au moins il est pour moi), mais la description suivante moins formelle aussi des sommes standard, il assez bien (au moins pour ce cas):

  

Un objet qui est accessible via un pointeur restreindre qualifié a une association spéciale   avec ce pointeur. Cette association, définie dans 6.7.3.1 ci-dessous, nécessite que tous les accès à cette utilisation de l'objet, directement ou indirectement, la valeur de ce pointeur particulier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top