Dlaczego następujące kompilacji w C++?Wiele operacji przedwstępnych na zmiennej w C++ (C?)
int phew = 53;
++++++++++phew ;
Ten sam kod kończy się niepowodzeniem w C, dlaczego?
Dlaczego następujące kompilacji w C++?Wiele operacji przedwstępnych na zmiennej w C++ (C?)
int phew = 53;
++++++++++phew ;
Ten sam kod kończy się niepowodzeniem w C, dlaczego?
To dlatego, że w C++
operatora preinkrementuj powraca się lvalue
i wymaga jego operandu być lvalue
.
++++++++++phew ;
w interpretować jako ++(++(++(++(++phew))))
Jednak kod wywołuje Undefined Behaviour
ponieważ staramy się zmodyfikować wartość phew
więcej niż raz pomiędzy dwoma sequence points.
W C
operator preinkrementuj powraca się rvalue
i wymaga jego operandu być lvalue
. Twój kod nie zostanie skompilowany w trybie C.
@Prasoon: Nie przejmuj się, zgaduję, jestem ciekawa, co przeczytałeś; "próbujesz zmodyfikować wartość uśpienia więcej niż raz między dwoma punktami sekwencji". Czy możesz podać adnotację do tej części normy, abym mógł przeczytać więcej na ten temat? –
@Merlyn Morgan-Graham: Przeczytaj ten artykuł Steve Summit: http://c-faq.com/expr/seqpoints.html. –
'Komentarz" Ta specyfikacja musi być przestrzegana tylko wtedy, gdy istnieje więcej niż jeden dostęp między sekwencjami punktów lub dla obiektów zadeklarowanych przy użyciu klasy pamięci masowej. W przypadku dewelopera występuje modyfikacja . Dopóki implementacja przyniesie oczekiwany rezultat, może robić to, co lubi. –
Uwaga: dwa raporty o usterkach DR#637 i DR#222 są ważne, aby zrozumieć uzasadnienie zachowania poniżej.
Dla wyjaśnienia, w C++ 0x istnieją value computations
i side effects
. Efektem ubocznym na przykład jest przydział, a obliczenie wartości określa, do czego odnosi się l-wartość lub odczytuje wartość z l-wartości. Zauważ, że C++ 0x nie ma już punktów sekwencyjnych, a te rzeczy są sformułowane w terminach "zsekwencjonowane przed"/"zsekwencjonowane po". I stwierdzono, że
Jeśli efektem ubocznym na skalarnym obiektu jest unsequenced w stosunku do każdej innej efektem ubocznym tego samego skalarnego obiektu lub obliczeń wartość używając wartość samego skalarnego obiektu, zachowanie jest niezdefiniowane.
++v
odpowiada v += 1
co jest równoważne v = v + 1
(z wyjątkiem, że V jest analizowany tylko raz). To daje ++ (v = v + 1)
, który napiszę jako inc = inc + 1
, gdzie inc
odnosi się do wyniku lwartości v = v + 1
.
W C++ 0x ++ ++v
nie jest niezdefiniowanym zachowaniem, ponieważ dla a = b
przypisanie jest sekwencjonowane po obliczeniu wartości b i a, ale przed obliczeniem wartości wyrażenia przypisania. Wynika z tego, że przypisanie w v = v + 1
jest sekwencjonowane przed obliczeniem wartości inc
. A przypisanie w inc = inc + 1
jest sekwencjonowane po obliczeniu wartości inc
. Ostatecznie oba przypisania zostaną zsekwencjonowane i nie ma niezdefiniowanych zachowań.
Dobra odpowiedź. Podobnie 'int a = 4; ++ a = 5; 'nie wywoływałoby UB w C++ 0x, prawda? –
@Prasoon tak. Ustawiłoby 'a' na 5. Podobnie' a = ++ a; 'nie będzie UB, ale' a = a ++; 'będzie UB. –
@ Janhannes: Cool :-). Świat się zmienia. –
Dodanie tagu C++ 0x dla zabawy. :) –
Musi być standardowe pytanie, na które możemy odpowiedzieć w przypadku tego typu pytań. Wszystkie pytania (które otrzymujemy o tej porze roku od nowych studentów) mogą być szybko zamknięte i oznaczone jako przeczytane. –