92 votes

Quel est le résultat de + = en C et C ++?

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 avec gcc, j'obtiens une erreur:

 error: lvalue required as left operand of assignment
 

Mais si je le compile en tant que source C++ utilisant g++ je n’obtiens aucune erreur et quand j’exécute l’exécutable:

 i = 20
 

Pourquoi ce comportement différent?

132voto

dasblinkenlight Points 264350

La sémantique de l'add-opérateurs d'assignation est différent en C et C++:

Standard C99, 6.5.16, partie 3:

Un opérateur d'affectation stocke une valeur dans l'objet désigné par l'opérande de gauche. Un affectation de l'expression a la valeur de l'opérande gauche après l'affectation, mais n'est pas un lvalue.

En C++ 5.17.1:

L'opérateur d'affectation (=) et le composé des opérateurs d'affectation à un groupe de droite à gauche. Tous exigent une modifiables lvalue comme leur opérande de gauche et de retourner une lvalue avec le type et la valeur de l'opérande gauche après la cession a eu lieu.

EDIT : Le comportement de l' (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 d' aix pour les parties pertinentes des normes.

51voto

NPE Points 169956

En plus d'être invalide le code en C, la ligne

(i+=10)+=10;

seraient le résultat d'un comportement indéterminé en C et C++03, car il serait de modifier i deux fois entre la séquence de points.

Pourquoi il est autorisé à compiler en C++:

[C++N3242 5.17.1] L'opérateur d'affectation (=) et le composé des opérateurs d'affectation à un groupe de droite à gauche. Tous besoin d'un modifiable lvalue comme leur opérande de gauche et de retourner une lvalue se référant à l'opérande de gauche.

Le même paragraphe continue à dire que

Dans tous les cas, la cession est séquencé après la valeur le calcul de la droite et de la gauche opérandes, et avant que la valeur de calcul de l'expression d'affectation.

Ceci suggère que, en C++11, l'expression n'a plus un comportement indéterminé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X