Pourquoi ce code ne se compile pas en raison d'une erreur:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << ++(i++) << " " << i << endl;
    return 0;
}

Bien que ce code compile:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << (++i)++ << " " << i << endl;
    return 0;
}

Je ne comprends pas ça. De mon point de vue, il serait assez raisonnable de compiler le premier morceau. L'expression ++ (i ++) signifierait simplement prendre i, l'incrémenter et le sortir, puis l'incrémenter à nouveau.

Je ne parle pas d'un comportement indéfini dans le débordement int. Je ne sais pas du tout sur les valeurs r et l au moment de la rédaction de la question et je me fiche de savoir pourquoi ++ i est considéré comme une valeur l, mais i ++ ne l'est pas.

2
Yaroslav 7 juil. 2017 à 21:18

3 réponses

Meilleure réponse

En effet, les opérateurs post-incrémentation et pré-incrémentation renvoient des valeurs de types différents. Le résultat de la post-incrémentation est ce qu'on appelle une «rvalue», ce qui signifie qu'elle ne peut pas être modifiée. Mais le pré-incrémentation a besoin d'une valeur modifiable pour l'incrémenter!

D'un autre côté, le résultat du pré-incrément est une valeur l, ce qui signifie qu'il peut être modifié en toute sécurité par le post-incrément.

Et la raison des règles ci-dessus est le fait que la post-incrémentation doit renvoyer une valeur de l'objet telle qu'elle était avant l'application de l'incrément. À propos, c'est pourquoi, en général, les post-incréments sont considérés comme plus chers que les pré-incréments lorsqu'ils sont utilisés sur des objets non intégrés.

6
Rakete1111 7 juil. 2017 à 18:29

En bref, la différence est qu'en C ++, vous pouvez utiliser n'importe quel nombre pair de plus (limité uniquement par les limites du compilateur) pour l'opérateur d'incrémentation de préfixe comme celui-ci

++++++++++++++++i;

Et seulement deux avantages pour l'opérateur de post-incrémentation

i++;

L'opérateur d'incrémentation de suffixe renvoie une valeur (The C ++ Standard, 5.2.6 Increment and decrement)

1 La valeur d'une expression postfix ++ est la valeur de son opérande . [Remarque: la valeur obtenue est une copie de la valeur d'origine —End note]

Alors que l'opérateur d'incrémentation du préfixe renvoie son opérande après l'incrémentation (The C ++ Standard, 5.3.2 Increment and decrement)

1 ... Le résultat est l'opérande mis à jour; c'est une lvalue ...

Contrairement à C ++ en C, vous ne pouvez également appliquer que deux plus à un objet en utilisant l'opérateur d'incrémentation du préfixe. :) Ainsi, le compilateur C émettra une erreur pour une telle expression comme celle-ci

++++++++++++++++i;
2
Vlad from Moscow 7 juil. 2017 à 18:40

Lorsque vous le compilez avec clang, vous obtenez un message d'erreur qui dit tout.

<source>:8:13: error: expression is not assignable
cout << ++(i++) << " " << i << endl;

Il est peut-être bon de commencer avec l'opérateur ++. En fait, c'est un raccourci pour i = i + 1. Maintenant, si nous regardons la version i ++ de postfix, elle dit en standard qu'elle renvoie une copie de la valeur d'origine et que side efect elle incrémente la valeur d'origine. Donc, à partir de (i ++), vous obtenez rvalue et essayez de lui attribuer et comme nous le savons, vous ne pouvez pas attribuer à rvalue.

1
Marek Vitek 7 juil. 2017 à 18:58