2016-02-17 8 views

Odpowiedz

11

w C++ 11 i później UB pojawia się, gdy istnieją dwa zapisy albo zapisu i odczytu, które są unsequenced i dostęp do tej samej pamięci Lokalizacja. Ale ++x jest równoważne x+=1, więc ++ ++n1 jest równoważne (n1+=1)+=1, a tutaj odczyty i zapisy odbywają się w ściśle określonej sekwencji z powodu właściwości przypisania i operatorów przypisania złożenia: najpierw czytany jest n1, następnie zapisywany jest jeden plus oryginalna wartość, następnie wynikowa wartość zostanie ponownie odczytana, a następnie zostanie odesłana jedna wartość plus.

W języku C++ 03 ten był UB, ze względu na starą regułę, o której wspominasz: nie ma żadnego punktu sekwencyjnego między dwiema modyfikacjami. Ale w C++ 11 nie ma już żadnych punktów sekwencyjnych; zamiast tego jest "zsekwencjonowany przed" częściowy porządek.

+1

Stało się to zbyt skomplikowane – Slava

2

Zobacz odpowiedź Brian's na prostsze warunki,.

To przyczyna prawny standard C++ tak mówi, podkreślenia są moje ... Idąc w projekcie C++ 14

5.3.2 Przyrost i ubytek [expr.pre.incr]

Operand z przedrostka ++ jest modyfikowany przez dodanie 1 lub ustawienie na wartość true, jeśli jest jest bool (to użycie jest przestarzałe). Operand będzie podlegał modyfikowalnej l-wartości. Typ argumentu operacji powinien być typem arytmetycznym lub wskaźnikiem dla całkowicie zdefiniowanego typu obiektu. Wynikiem jest zaktualizowany operand ; jest to l-wartość i jest polem bitowym, jeśli operand jest polem bitowym. Jeśli x nie jest typu BOOL, wyrażenie ++ x jest odpowiednikiem x + = 1

Tak, jest to całkowicie legalne

#include <iostream> 
using namespace std; 

int main(){ 
    int x =8; 
    int y = ++ ++ ++ ++ ++ ++ ++ ++ x; 
    cout << x << " " << y; 

} 

Output

16 16 

1.9 Programu wykonanie [wersja wstępna]

... Jeśli efektem ubocznym na skalarnym obiektu jest unsequenced względem obu inny efekt uboczny na samym skalarnego obiektu lub obliczania wartości stosując wartość samym skalarnego obiektu, zachowanie jest niezdefiniowany. ...

I to przykład dołączone:

void f(int, int); 
void g(int i, int* v) { 
i = v[i++]; // the behavior is undefined 
i = 7, i++, i++; // i becomes 9 
i = i++ + 1; // the behavior is undefined 
i = i + 1; // the value of i is incremented 
f(i = -1, i = -1); // the behavior is undefined 
} 
+0

"Zobacz odpowiedź Briana na odpowiedź" ... przepraszam, nie mogłem się oprzeć. –

+0

Nie zapytałem, czy jest to poprawne składniowo, zapytałem, czy to prowadzi do UB, co jest zupełnie inne. – Slava

+0

Zacytowałem standard w odniesieniu do samych operatorów, "... wynikiem jest l-value ..." zasadniczo ma jedną część odpowiedzi tam ... – WhiZTiM

Powiązane problemy