Rozważmy następujący kod:
int main() {
int i = 2;
int b = ++i++;
return 3;
}
Kompiluje się z następującymi błędami:
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
Brzmi dla mnie uczciwie. Przyrost Postfiksa ma wyższy priorytet niż Przyrost Prefiksu , więc kod jest analizowany jako int b = ++(i++);
i i
jest wartością rvalue. Stąd błąd.
Rozważmy teraz ten wariant z nawiasami, aby zastąpić domyślne priorytety:
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
Ten kod kompiluje się i zwraca 3. Samo w sobie brzmi to uczciwie, ale wydaje się być sprzeczne z pierwszym kodem.
Powstaje pytanie: dlaczego (++i)
to lvalue
, kiedy i
nie jest?
Dzięki!
AKTUALIZACJA: powyższy komunikat o błędzie pochodzi z gcc (x86-64 9.2). Oto dokładne renderowanie: błąd z gcc
Clang x86-64 9.0.0 ma zupełnie inny komunikat: błąd z clang
<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
Dzięki GCC masz wrażenie, że problem dotyczy operatora Postfiksa, a następnie możesz wędrować, dlaczego ++i
jest OK, a i
nie jest, stąd moje pytanie. W przypadku Clanga jest wyraźniejsze, że problem dotyczy operatora prefiksu.
Odpowiedzi:
i
i++i
oba są wartościami, alei++
są wartością.++(i++)
nie może być ważny, jako przedrostek++
jest stosowany doi++
, który jest rvalue. Ale(++i)++
jest w porządku, ponieważ++i
jest wartością.Zauważ, że w C sytuacja jest inna;
i++
i++i
oba są wartościami. (Jest to przykład tego, dlaczego ludzie powinni przestać zakładać, że C i C ++ mają te same reguły. Ludzie umieszczają te założenia w swoich pytaniach, które należy następnie obalić.)źródło
Ta deklaracja
jest równa
Operator przyrostka Postfiks zwraca wartość argumentu przed przyrostem.
Ze standardu C ++ 17 (8.2.6 Zwiększanie i zmniejszanie)
Podczas gdy operator jednostkowej inkrementacji zwraca wartość po jej inkrementacji. Więc ta deklaracja
jest ważny. Możesz na przykład pisać
Ze standardu C ++ 17 (8.3.2 Zwiększanie i zmniejszanie)
Zwróć uwagę, że w C oba operatory zwracają wartość zamiast wartości. Więc w C ta deklaracja
jest nieważny.
źródło
Nie.
i
To nie jest wartość.i
jest wartością.i++
jest wartością (prvalue, aby być konkretnym).źródło