Kolejność oceny i niezdefiniowane zachowanie

Mówiąc w kontekście standardu C ++ 11 (który nie ma już pojęcia punktów sekwencji, jak wiecie), chcę zrozumieć, jak zdefiniowano dwa najprostsze przykłady.

int i = 0;

i = i++;   // #0

i = ++i;   // #1

Istnieją dwa tematy dotyczące SO, które wyjaśniają te przykłady w kontekście C ++ 11.Tutaj tak powiedziano#0 przywołuje UB i#1 jest dobrze zdefiniowany.Tutaj powiedziano, że oba przykłady są niezdefiniowane. Ta dwuznaczność bardzo mnie myli. Czytałem to dobrze skonstruowaneodniesienie trzy razy, ale temat wydaje mi się zbyt skomplikowany.

.

Przeanalizujmy przykład#0: i = i++;.

Odpowiednie cytaty to:

Obliczanie wartości wbudowanych operatorów postinkrementacji i postdecrement jest sekwencjonowane przed efektem ubocznym.

Efekt uboczny (modyfikacja lewego argumentu) wbudowanego operatora przypisania i wszystkich wbudowanych operatorów przypisania złożonego jest sekwencjonowany po obliczeniu wartości (ale nie skutkach ubocznych) zarówno lewego, jak i prawego argumentu, i jest sekwencjonowany przed obliczanie wartości wyrażenia przypisania (to znaczy przed zwróceniem odwołania do zmodyfikowanego obiektu)

Jeśli efekt uboczny na obiekcie skalarnym nie zostanie uporządkowany względem innego efektu ubocznego na tym samym obiekcie skalarnym, zachowanie jest niezdefiniowane.

W miarę tego, efekt uboczny operatora przypisania nie jest sekwencjonowany z efektami ubocznymi jego lewych i prawych argumentów. Tak więc efekt uboczny operatora przypisania nie jest sekwencjonowany z efektami ubocznymii++. Więc#0 wywołuje UB.

.

Przeanalizujmy przykład#1: i = ++i;.

Odpowiednie cytaty to:

Efekt uboczny wbudowanych operatorów preinkrementacji i predecrementacji jest sekwencjonowany przed obliczeniem wartości (niejawna reguła wynikająca z definicji jako przydział złożony)

Efekt uboczny (modyfikacja lewego argumentu) wbudowanego operatora przypisania i wszystkich wbudowanych operatorów przypisania złożonego jest sekwencjonowany po obliczeniu wartości (ale nie skutkach ubocznych) zarówno lewego, jak i prawego argumentu, i jest sekwencjonowany przed obliczanie wartości wyrażenia przypisania (to znaczy przed zwróceniem odwołania do zmodyfikowanego obiektu)

Jeśli efekt uboczny na obiekcie skalarnym nie zostanie uporządkowany względem innego efektu ubocznego na tym samym obiekcie skalarnym, zachowanie jest niezdefiniowane.

Nie widzę, jak ten przykład różni się od tego#0. To wydaje się być dla mnie UB z tego samego powodu, co#0. Efekt uboczny przydziału nie jest sekwencjonowany z efektem ubocznym++i. To wydaje się być UB. Temat lubi powyżej mówi, że jest dobrze zdefiniowany. Czemu?

.

Pytanie: jak mogę zastosować przytoczone reguły, aby określić UB przykładów. Bardzo proste wyjaśnienie byłoby bardzo mile widziane. Dziękuję Ci!

questionAnswers(2)

yourAnswerToTheQuestion