c++ - Warum ist "++ i++" ungültig, während(++ i)++ gültig ist?




operators lvalue (2)

Betrachten wir den folgenden Code:

int main() {
    int i = 2;
    int b = ++i++;
    return 3;
}

Es wird mit folgendem Fehler kompiliert:

<source>: In function 'int main()':

<source>:3:16: error: lvalue required as increment operand

    3 |     int b = ++i++;

      |                ^~

Das klingt für mich fair. Das Postfix-Inkrement hat eine höhere Priorität als das Präfix-Inkrement, sodass der Code wie folgt analysiert wird: int b = ++(i++); und i bin ein Wert. Daher der Fehler.

Betrachten wir nun diese Variante mit Klammern, um die Standardprioritäten zu überschreiben:

int main() {
    int i = 2;
    int b = (++i)++;
    return 3;
}

Dieser Code kompiliert und gibt 3 zurück. Das klingt für sich genommen fair, scheint aber im Widerspruch zum ersten Code zu stehen.

Die Frage: Warum (++i) ist ein lvalue wenn i nicht ist?

Vielen Dank!

UPDATE: Die oben gezeigte Fehlermeldung stammte von gcc (x86-64 9.2). Hier ist das genaue Rendering: Fehler mit gcc

Clang x86-64 9.0.0 hat eine ganz andere Meldung: Fehler mit Clang

<source>:3:13: error: expression is not assignable

    int b = ++i++;

            ^ ~~~

Mit GCC bekommen Sie den Eindruck, dass das Problem mit dem Postfix-Operator zusammenhängt, und Sie können dann überlegen, warum ++i in Ordnung bin, während i es nicht bin, daher meine Frage. Mit Clang wird klarer, dass das Problem beim Präfixoperator liegt.


Daher wird der Code als int b = ++ (i ++) analysiert. und ich bin ein Wert.

Nein, i bin kein Wert. i bin ein Wert. i++ ist ein Wert (prvalue um genau zu sein).


Diese Erklärung

int b = ++i++;

ist äquivalent zu

int b = ++( i++ );

Der Postfix-Inkrement-Operator gibt den Wert des Operanden vor dem Inkrement zurück.

Aus dem C ++ 17 Standard (8.2.6 Inkrementieren und Dekrementieren)

1 Der Wert eines Postfix ++ - Ausdrucks ist der Wert seines Operanden ... Das Ergebnis ist ein Wert .

Während der unäre Inkrementoperator nach seinem Inkrement lvalue zurückgibt. Also diese Erklärung

int b = (++i)++;

ist gültig. Du könntest zum Beispiel schreiben

int b = (++++++++i)++;

Aus dem C ++ 17 Standard (8.3.2 Inkrementieren und Dekrementieren)

1 Der Operand von Präfix ++ wird durch Hinzufügen von 1 geändert. Der Operand muss ein änderbarer Wert sein. Der Typ des Operanden muss ein anderer arithmetischer Typ als cv bool oder ein Zeiger auf einen vollständig definierten Objekttyp sein. Das Ergebnis ist der aktualisierte Operand. Es ist ein Wert , und es ist ein Bitfeld, wenn der Operand ein Bitfeld ist.

Beachten Sie, dass in C beide Operatoren einen Wert anstelle von lvalue zurückgeben. Also in C diese Erklärung

int b = (++i)++;

ist ungültig.





pre-increment