Czy standard definiuje co pojawi się na wyjściu po poniższych instrukcjach?
int x = 2, y = 1;
cout << x++ + y + x;
Czy standard definiuje co pojawi się na wyjściu po poniższych instrukcjach?
int x = 2, y = 1;
cout << x++ + y + x;
Prześledź po kolei wyrażenia i dostaniesz wynik.
(2 + 1 + 3)
EDIT:
Jednak nie. Tak jak mówi @Rev, nigdy nie zagłębiałem się w sumie w kolejność wyrażeń w C++ a pod .NET okazuje się, że jest dosyć inaczej.
Nie, ponieważ plus nie jest zaliczany do sequence points.
@xeo545x39, undefined behavior i tyle.
Nie wiem co definiuje standard, ale GCC daje wynik 6
, Open Watcom daje 6
, a Visual C++ daje 5
.
Czy dałoby się zaimplementować operator postinkrementacji ++ w taki sposób, żeby inkrementacja była dokonywana po wykonaniu całego wyrażenia?
w tym wypadku:
x++ + y + x; // tu x jest jeszcze równe 5
// wyrażenie się skonczyło, x = 6
Mam do wykonania właśnie takie zadanie.
"operatory postfiksowe ++ i -- powinny być zaimplementowane w taki sposób, aby rzeczywiste zwiększenie/zmniejszenie wartości nastąpiło po wykonaniu całego wyrażenia"
"Kluczem jest przyjęcie, że "całe wyrażenie" w zadaniu oznacza wyrażenie, które nie jest podwyrażeniem innego wyrażenia. Jednak naiwna implementacja (z §12.2) pewnie będzie zawierała UB z powodu §1.9.15."
To co podałeś w pierwszym poście to undefined behavior. Nie da się tego naprawić w przypadku typów wbudowanych.
W przypadku typów zdefiniowanych przez użytkownika z przeciążonymi operatorami wygląda to tak (y
nie ma znaczenia):
x++ + x
x.operator+(x.operator++(int), x)
Wiadomo na pewno, że argumenty funkcji operator+
zostaną obliczone przed wywołaniem tej funkcji.
Jeżeli operator+
przyjmuje swoje argumenty przez wartość to jest tak: W dalszym ciągu nie jest zdefiniowane, czy najpierw zostanie "obczliony" argument x
(to chyba jest glvalue to prvalue conversion?) czy wywołana zostanie funkcja operator++(int)
. Jeżeli kolejność nie jest znana a funkcja operator++(int)
ma efekty uboczne (modyfikuje coś wewnątrz x
), to w dalszym ciągu jest to undefined behavior. Gdyby ta funkcja nie miała efektów ubocznych, kod jest w porządku.
Jeżeli operator+
przyjmuje oba argumenty przez referencję to kod wydaje się być w porządku, nawet, jeżeli funkcja operator++(int)
zmienia coś wewnątrz x
. W przypadku referencji argument x
nie wiąże się z żadną operacją (to nie będzie value computation), a więc nie ma wtedy operacji, których kolejność nie jest określona - zostaje tylko wywołanie operator++(int)
.
To trochę skomplikowane i dziwne, więc nie gwarantuję, że to co napisałem jest poprawne. ;-)
http://ideone.com/UsE8Fs
@Endrju: zdaje się, że zrobiłem jak pisałeś i zdaje się, że nie do końca działa.