2013-03-12 20 views
13

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?

+2

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

+0

@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ń. –

+0

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

Odpowiedz

12

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; 
+4

"analizowane osobno" nie wskazuje nic na sekwencjonowanie w oświadczeniu o wykonaniu. Czy jest o to silniejsze wskazanie w standardzie? –

+0

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

8

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.

+0

Przypisy nie są normatywne w normie ISO, więc nie określają niczego, są jedynie tekstem informacyjnym. – Lundin

+0

Oprócz tego, co powiedział Lundin, słowo "zwykle" nie daje mi żadnych ciepłych uczuć o gwarancji sekwencji. – IronMensan

+1

@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. –