En C, --x
est une valeur, pas une lvalue. Son effet est de décrémenter x
et l'évaluer à la valeur nouvellement attribuée de x
. Puisque --x
n'est pas une lvalue, elle ne peut pas être décrémentée.
En C++, --x
est une lvalue, pas une rvalue. Son effet est de décrémenter x
et évaluer à x
en tant que valeur l. Puisque --x
est à nouveau une lvalue, elle peut être décrémentée à nouveau.
La raison pour laquelle il est logique que --x
pour être une lvalue en C++ est parce que C++ a introduit les types de référence. Étant donné que
void f(int &);
int i;
il peut être judicieux d'appeler f(--i)
qui passe i
par référence après l'avoir décrémenté.
Puisque le C n'a pas de types de référence, il n'y a pas d'utilité à --i
étant une lvalue. Historiquement, cela n'a jamais été le cas, et contrairement au C++, le C n'a jamais eu de raison impérieuse de changer les règles.
Notez que le C++ a nécessité des modifications plus importantes que de faire --x
une lvalue pour que cela fonctionne. Création de --x
une lvalue, sans rien d'autre, rendrait --x
comportement non défini, parce qu'il n'y aurait pas de point de séquence entre la modification de la x
et la conversion subséquente de lval en valeur. C'est encore plus évident pour ----x
. Le C++ a dû modifier les règles de séquençage pour que cela fonctionne. En C, les modifications des règles de séquençage pourraient poser des problèmes aux compilateurs existants pour se conformer aux nouvelles règles, de sorte que de telles modifications seraient probablement rejetées à moins qu'elles ne présentent un avantage important.