Ce code C99 produit-il un comportement indéfini ?
Non. Il ne produira pas de comportement indéfini. a[0]
est modifié une seule fois entre deux points de séquence (le premier point de séquence est à la fin de l'initialisateur int a[3] = {0, 0, 0};
et le deuxième est après l'expression complète a[a[0]] = 1
).
Il ne mentionne pas la lecture d'un objet pour déterminer l'objet lui-même à modifier. Ainsi, cette déclaration pourrait produire un comportement non défini.
Un objet peut être lu plus d'une fois pour se modifier et son comportement est parfaitement défini. Regardez cet exemple
int x = 10;
x = x*x + 2*x + x%5;
Le deuxième énoncé de la citation dit :
En outre, le valeur préalable ne doit être lu que pour déterminer la valeur à stocker.
Tous les x
dans l'expression ci-dessus est lu pour déterminer la valeur de l'objet x
lui-même.
NOTE : Notez qu'il y a deux parties de la citation mentionnée dans la question. La première partie dit : Entre le point de séquence précédent et le suivant, la valeur stockée d'un objet est modifiée au maximum une fois par l'évaluation d'une expression. et
donc l'expression comme
i = i++;
relève de UB (deux modifications entre les points de séquence précédents et suivants).
La deuxième partie dit : En outre, la valeur antérieure ne doit être lue que pour déterminer la valeur à stocker. et donc les expressions comme
a[i++] = i;
j = (i = 2) + i;
invoquer UB. Dans les deux expressions i
n'est modifié qu'une seule fois entre le point de séquence précédent et le suivant, mais la lecture du point de séquence le plus à droite i
ne déterminent pas la valeur à stocker dans i
.
Dans la norme C11, cela a été modifié comme suit
6.5 Expressions :
Si un effet secondaire sur un objet scalaire est non séquencé par rapport à un effet secondaire différent sur le même objet scalaire ou un calcul de valeur utilisant la valeur du même objet scalaire, le comportement est indéfini. [...]
Dans l'expression a[a[0]] = 1
il n'y a qu'un seul effet secondaire à a[0]
et le calcul de la valeur de l'indice a[0]
est séquencé avant le calcul de la valeur de a[a[0]]
.