Tytuł pytania mówi wszystko: czy deklaracje formularza int a = 0, b = a
mają niezdefiniowane zachowanie?Czy `int a = 0, b = a` ma niezdefiniowane zachowanie?
Odpowiedz
Nie, to jest dobrze zdefiniowane. Jest to deklaracja z dwoma deklaratorami: a
i b
. Każdy deklarator ma inicjator.
Każdy startowe declarator w zgłoszeniu analizowano osobno, jak gdyby była w zgłoszeniu sama.
Oznacza to, że linia jest traktowany jak:
int a = 0;
int b = a;
"analizowane osobno" nie wskazuje nic na sekwencjonowanie w oświadczeniu o wykonaniu. Czy jest o to silniejsze wskazanie w standardzie? –
Aby odpowiedzieć na własne uwagi, myślę, że trzeba zacytować 1.9/14 na temat oceny pełnych wyrażeń, które są sekwencjonowane przed oceną kolejnych pełnych wyrażeń. Zobacz komentarz do http://stackoverflow.com/a/6414247/19563. –
Nie, nie ma Undefined Behavior.
za § 8/3 z C++ 11 Standard:
Każdy startowe declarator w zgłoszeniu są analizowane osobno, jak gdyby była w zgłoszeniu sam
Również jako stopki 97 określa:
zgłoszenie kilka declarators zwykle równoważna odpowiedniej sekwencji zgłoszeń każdy z jednym deklaratorem . Oznacza to
T D1, D2, ... Dn;
zazwyczaj (*) równoważne
T D1; T D2; ... T Dn;
Oznacza to, że a
jest inicjowana, następnie b
inicjowany jest i przyjmuje wartości z a
. Zauważ również, że nawet jeśli tak nie było, to istnieje quite a long debate on SO, czy to byłoby UB, czy nie, i osiągnięto konsensus w sprawie tego, że nie jest to UB.
(*): Jak wyjaśnia Olaf DIETSCHE w komentarzach, sytuacje, w których równoważność ta robi nie chwyt są wymienione później w tym samym przypisie.
Przypisy nie są normatywne w normie ISO, więc nie określają niczego, są jedynie tekstem informacyjnym. – Lundin
Oprócz tego, co powiedział Lundin, słowo "zwykle" nie daje mi żadnych ciepłych uczuć o gwarancji sekwencji. – IronMensan
@Lundin: Przypisy nie są normatywne, to prawda. Ale często są tam po to, aby wskazać rzeczy, które można inaczej wywnioskować ze Standardu poprzez bardziej złożone formalne odliczenia. Nie byłem w stanie przeprowadzić tych dedukcji osobiście, ale myślałem, że może to być odpowiednie odniesienie, przynajmniej jako deklaracja zamiaru. –
- 1. Czy w wyrażeniu a^= b^= a^= b są punkty sekwencyjne, czy jest niezdefiniowane?
- 2. Odcinek całkowity: czy // b == int (a/b) jest prawdziwe dla wszystkich liczb całkowitych a, b?
- 3. Czy zawsze mam `(a/b * b) + a% b == a`, gdy b nie jest zerem?
- 4. Różnica między || a = b i a = a || b w rubin?
- 5. Dlaczego a jest niezdefiniowane, gdy b wynosi 3 w var a = b = 3?
- 6. Dlaczego fold left oczekuje (a -> b -> a) zamiast (b -> a -> a)?
- 7. Dlaczego (a | b) jest równoważne z - (a & b) + b?
- 8. numexpr.evaluate ("a + b", out = a)
- 9. Jeśli podwójne a = 0.0, czy mogę porównać * b == 0 bezpośrednio?
- 10. Rodzaj minBy [B] (f: ((A, B)) ⇒ B) (ukryte CMP: Kolejność [B]): (A, B)
- 11. Dlaczego Java 8 wprowadzać * Integer.sum (int a, int b) *
- 12. Różnica między sort(), sort (funkcja (a, b) {return a-b;}); i sortowanie (funkcja (a, b) {...})
- 13. (Python) Jak uzyskać przekątną (A * B) bez wykonywania A * B?
- 14. Jak najlepiej sprawdzić, czy A xor B ma wartość null?
- 15. Redukujące Iterable [Albo [A, B]] na [A, Iterable [B]]
- 16. W jaki sposób "a <= b && b <= a && a! = B" może być prawdziwe?
- 17. Jak podzielić F [A \/B] do (F [A], M [B])
- 18. Oracle SQL UNIQUE A do B, B do A
- 19. Co oznacza "int * a = (int [2]) {0, 2};" dokładnie zrobić?
- 20. Numpy Różnica pomiędzy punktu (a, b) i (a * b) .sum()
- 21. klasa A ma jeden parametr, ale typ B ma jeden:
- 22. Wyrażenia regularne zastępujące {{a, b}} i {{a}}
- 23. Czy <'a, 'b: 'a> oznacza, że życie "b musi przeżyć całe życie"?
- 24. RegEx dla^b zamiast pow (a, b)
- 25. Jaka jest różnica między "(a b c) a (listą" a "b" c)?
- 26. Jak pozwolić funkcji [a] -> [a] działać na [(a, Int)]?
- 27. Różnica między +++++ B i A ++ + ++ b
- 28. C++: czy funkcja ponownie deklaruje niezdefiniowane zachowanie?
- 29. Niezdefiniowane zachowanie operatorów w algorytmie zamiany XOR?
- 30. Szyny 3: Jak sprawdzić, czy A <B, gdzie A i B są atrybutami modelu?
Następne pytanie brzmi, czy taki wiersz kodu ma sens w jakimkolwiek realnym scenariuszu? Czy istnieje jakikolwiek powód, dla którego napiszesz to, a nie 'int a = 0; int b = 0; '? – Lundin
@Lundin Gdy wartość 'a' jest wynikiem funkcji, której nie chcesz wykonywać dwukrotnie, co jest moim przypadkiem. Potrzebuję dwóch kopii tej wartości: jednej do wyprowadzenia i jednej, którą muszę zmodyfikować podczas wykonywania innych obliczeń. –
możliwy duplikat [Czy przecinek na liście zmiennych jest punktem sekwencyjnym?] (Http://stackoverflow.com/questions/6414030/is-the-comma-in-a-variable-list-a-sequence-point) i [Czy kolejność przypisywania na liście inicjalizowanych zmiennych jest niezdefiniowana?] (http://stackoverflow.com/questions/12729962/jest-pokazanie-w-listowaniu-instruowanych-zmiennych -undefined? lq = 1) ... –