Prenons le code suivant:
int main() {
int i = 2;
int b = ++i++;
return 3;
}
Il se compile avec ce qui suit avec une erreur:
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
Cela me semble juste. L'incrément de suffixe a une priorité plus élevée que l'incrément de préfixe, donc le code est analysé comme int b = ++(i++);
et i
est une valeur r. D'où l'erreur.
Considérons maintenant cette variante entre parenthèses pour remplacer les priorités par défaut:
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
Ce code compile et renvoie 3. À lui seul, cela me semble juste, mais il semble en contradiction avec le premier code.
La question: pourquoi (++i)
un lvalue
quand i
ne l'est pas?
Merci!
MISE À JOUR: le message d'erreur ci-dessus provenait de gcc (x86-64 9.2). Voici le rendu exact: erreur avec gcc
Clang x86-64 9.0.0 a un message assez différent: erreur avec clang
<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
Avec GCC, vous avez l'impression que le problème est avec l'opérateur postfix et vous pouvez alors vous demander pourquoi ++i
est OK alors que ce i
n'est pas le cas, d'où ma question. Avec Clang, il est plus clair que le problème vient de l'opérateur de préfixe.
Réponses:
i
et++i
sont tous les deux lvalues, maisi++
est une rvalue.++(i++)
ne peut pas être valide, car le préfixe++
est appliqué ài++
, qui est une valeur r. Mais(++i)++
c'est bien parce que++i
c'est une valeur.Notez qu'en C, la situation est différente;
i++
et++i
sont tous les deux des valeurs. (C'est un exemple de la raison pour laquelle les gens devraient cesser de supposer que C et C ++ ont les mêmes règles. Les gens insèrent ces hypothèses dans leurs questions, qui doivent ensuite être réfutées.)la source
Cette déclaration
est équivalent à
L'opérateur d'incrémentation postfixe renvoie la valeur de l'opérande avant l'incrémentation.
De la norme C ++ 17 (8.2.6 Incrémentation et décrémentation)
Tandis que l'opérateur d'incrément unaire renvoie lvalue après son incrément. Donc, cette déclaration
est valable. Vous pourriez par exemple écrire
De la norme C ++ 17 (8.3.2 Incrémentation et décrémentation)
Faites attention qu'en C, les deux opérateurs retournent une valeur au lieu de lvalue. Donc en C cette déclaration
est invalide.
la source
Non
i
n'est pas une valeur.i
est une valeur l.i++
est une rvalue (prvalue pour être spécifique).la source