Technicznie rzecz biorąc, ogólnie jest to niezdefiniowane zachowanie .
Ale są dwa ważne aspekty odpowiedzi.
Instrukcja kodu:
std::cout << a++ << a;
jest oceniany jako:
std::operator<<(std::operator<<(std::cout, a++), a);
Norma nie definiuje kolejności obliczania argumentów funkcji.
Więc albo:
std::operator<<(std::cout, a++)
jest oceniany jako pierwszy lub
a
jest oceniany jako pierwszy lub
- może to być dowolna realizacja zdefiniowana w kolejności.
To zamówienie jest nieokreślone [Ref 1] zgodnie z normą.
[Odn. 1] C ++ 03 5.2.2 Wywołanie funkcji,
pkt 8
Kolejność oceny argumentów jest nieokreślona . Wszystkie skutki uboczne obliczeń wyrażeń argumentów obowiązują przed wprowadzeniem funkcji. Kolejność obliczania wyrażenia postfiksowego i listy wyrażeń argumentów jest nieokreślona.
Co więcej, nie ma punktu sekwencji między oceną argumentów funkcji, ale punkt sekwencji istnieje tylko po ocenie wszystkich argumentów [Ref 2] .
[Odn. 2] C ++ 03 1.9 Wykonanie programu [wprowadzenie.wykonanie]: Par.
17:
Podczas wywoływania funkcji (niezależnie od tego, czy funkcja jest wbudowana, czy nie), po ocenie wszystkich argumentów funkcji (jeśli istnieją) występuje punkt sekwencji, który ma miejsce przed wykonaniem jakichkolwiek wyrażeń lub instrukcji w treści funkcji.
Zauważ, że tutaj wartość c
jest dostępna więcej niż jeden raz bez interweniującego punktu sekwencji, w związku z tym standard mówi:
[Odn. 3] C ++ 03 5 Wyrażenia [wyraż]:
par. 4:
....
Pomiędzy poprzednim a następnym punktem sekwencji obiekt skalarny będzie miał swoją przechowywaną wartość zmodyfikowaną co najwyżej raz przez ocenę wyrażenia. Ponadto dostęp do wcześniejszej wartości jest możliwy tylko w celu określenia wartości, która ma być przechowywana . Wymagania niniejszego punktu muszą być spełnione dla każdego dopuszczalnego uporządkowania podwyrażeń pełnego wyrażenia; w przeciwnym razie zachowanie jest niezdefiniowane .
Kod modyfikuje c
więcej niż jeden raz bez interwencji punktu sekwencji i nie jest uzyskiwany dostęp do niego w celu określenia wartości przechowywanego obiektu. Jest to wyraźne naruszenie powyższej klauzuli, a zatem wynik zgodnie z zaleceniami normy to Undefined Behavior [Ref 3] .