Poprawność wyrażenia

0

Czy standard definiuje co pojawi się na wyjściu po poniższych instrukcjach?

int x = 2, y = 1;
cout << x++ + y + x;
0

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.

1

Nie, ponieważ plus nie jest zaliczany do sequence points.

@xeo545x39, undefined behavior i tyle.

0

Nie wiem co definiuje standard, ale GCC daje wynik 6, Open Watcom daje 6, a Visual C++ daje 5.

0

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."

3

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. ;-)

0
http://ideone.com/UsE8Fs

@Endrju: zdaje się, że zrobiłem jak pisałeś i zdaje się, że nie do końca działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1