J'ai le code suivant:
#include <stdio.h>
int main(int argc, char **argv) {
int i = 0;
(i+=10)+=10;
printf("i = %d\n", i);
return 0;
}
Si j'essaie de le compiler en tant que source C en utilisant gcc, j'obtiens une erreur:
error: lvalue required as left operand of assignment
Mais si je le compile en tant que source C ++ en utilisant g ++, je n'obtiens aucune erreur et lorsque j'exécute l'exécutable:
i = 20
Pourquoi ce comportement différent?
Réponses:
La sémantique des opérateurs d'affectation composée est différente en C et C ++:
Norme C99, 6.5.16, partie 3:
Dans C ++ 5.17.1:
EDIT: Le comportement de
(i+=10)+=10
en C ++ n'est pas défini en C ++ 98, mais bien défini en C ++ 11. Voir cette réponse à la question de NPE pour les parties pertinentes des normes.la source
(i+=10)+=10
comportement n'est pas défini en C ++, voir la réponse @aix.int f(int &y); f(x += 10);
- passer une référence à la variable modifiée dans une fonction.En plus d'être un code C invalide, la ligne
entraînerait un comportement non défini en C et C ++ 03 car il modifierait
i
deux fois entre les points de séquence.Quant à savoir pourquoi il est permis de compiler en C ++:
Le même paragraphe continue en disant que
Cela suggère qu'en C ++ 11, l'expression n'a plus de comportement indéfini.
la source
i
qui ne sont pas séquencées.i = j+=1
résulterait une valeur indéterminée. Dans le même paragraphe, vous citez "Dans tous les cas, l'affectation est séquencée après le calcul de la valeur des opérandes droit et gauche et avant le calcul de la valeur de l'expression d'affectation." Par conséquent, il(i+=10)+=10
est bien défini de fairei += 10; i += 10;
. D'autre part,(i+=10)+=(i+=10)
UB.