2016-02-17 11 views

risposta

11

In C++ 11 e più tardi, UB si verifica quando ci sono due operazioni di scrittura o una scrittura e una lettura che sono non in sequenza e accedere alla stessa memoria Posizione. Ma ++x equivale a x+=1, quindi ++ ++n1 equivale a (n1+=1)+=1 e qui le letture e le scritture avvengono in una sequenza rigorosa a causa delle proprietà degli operatori di assegnazione e di assegnazione composta: prima viene letto n1, quindi uno più il valore originale viene scritto, quindi il valore risultante viene nuovamente letto, quindi uno più quel valore viene riscritto.

In C++ 03, questo era UB, a causa della vecchia regola a cui si allude: non vi è alcun punto di sequenza tra le due modifiche. Ma in C++ 11 non ci sono più punti di sequenza; invece c'è l'ordine parziale "sequenziato prima".

+1

È diventato troppo complicato – Slava

2

Vedere risposta Brian's per termini più semplici,.

E 'causa legale lo standard C++ dice così, enfasi sono mie ... Andando dal progetto di C++ 14

5.3.2 Incremento e decremento [expr.pre.incr]

L'operando del prefisso ++ viene modificato aggiungendo 1 o impostato su true se è bool (questo uso è deprecato). L'operando deve essere un valore modificabile . Il tipo dell'operando deve essere un tipo aritmetico o un puntatore a un tipo di oggetto completamente definito. Il risultato è l'operando aggiornato ; è un lvalue ed è un campo di bit se l'operando è un campo di bit. Se x non è di tipo bool, l'espressione ++ x è equivalente a x + = 1

Quindi, questo è perfettamente legale

#include <iostream> 
using namespace std; 

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

} 

uscita

16 16 

1,9 Programma esecuzione [intro.execution]

... Se un effetto collaterale su un oggetto scalare è relativa non in sequenza a uno altro effetto secondario sulla stesso oggetto scalare o un valore di calcolo utilizzando il valore dello stesso oggetto scalare, il comportamento è non definito. ...

Ed è attaccato esempio:

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

"Vedi la risposta di Brian per la risposta vera" ... scusa, non ho potuto resistere. –

+0

Non ho chiesto se questo è sintatticamente corretto, ho chiesto se questo porta a UB, che è completamente diverso. – Slava

+0

Ho citato lo standard rispetto agli operatori stessi, "... il risultato è un lvalue ..." in pratica ha una parte della risposta ... – WhiZTiM

Problemi correlati