2010-11-22 7 views
7

Sì, ho letto l'articolo su sequence points. Tuttavia non riuscivo a capire perché ++i = 2 invocasse un comportamento indefinito? Il valore finale di i sarebbe 2 indipendentemente da qualsiasi cosa, quindi come mai l'espressione è ub?Ancora un'altra domanda relativa ai punti di sequenza

frammento di codice

int main() 
{ 
    int i =0; 
    ++i=2; 
    return 0; 
} 

dispiace il mio inglese non è molto buono.

risposta

9

Si si osserva tale valore sarà quello che si sostiene, è così che UB può manifestarsi tra gli altri possibili scenari. Il programma potrebbe produrre ciò che ti aspetti, generare dati non correlati, crash, dati corrotti o spendere tutti i tuoi soldi per ordinare la pizza. Una volta che lo standard C++ dice che alcuni costrutti sono UB, non dovresti aspettarti alcun comportamento specifico. I risultati osservati possono variare da un programma all'altro.

+0

ma come potrebbe il risultato essere diverso da 2? Ho provato alcuni compilatori online e offline tra cui gcc, msvC++, intel C++. non ho ottenuto nulla di diverso da 2. – AMS

+1

@AMS: Che cosa succede se il programma ha speso tutti i tuoi soldi o ha inviato tutte le tue password a terzi (http://stackoverflow.com/questions/908872/whats-the-worst-example- di-undefined-comportamento-realtà-possibile/3554343 # 3554343)? – sharptooth

+0

E questo non è affatto uno scherzo - ti incoraggio a seguire effettivamente il link e leggere la risposta dietro di esso. – sharptooth

0

Dallo stesso link esatto si sta fornendo:

  • Inoltre, il valore preventiva è accessibile solo per determinare il valore da memorizzare.

Che cosa significa? Significa che se un oggetto viene scritto all'interno di un'espressione completa , qualsiasi accesso a esso all'interno della stessa espressione deve essere direttamente coinvolto nel calcolo del valore da scrivere.

Qui sul lato sinistro dell'operatore =, l'accesso a i non è coinvolta nel calcolo del valore scritto.

0

++ i (dovrebbe essere) un valore di rvalore e, quindi, non può essere utilizzato come valore di lvalue, ma (++ i) = 2; dovrebbe funzionare bene Non credo che questo sia UB, ma, come sempre, potrei sbagliarmi.

+0

Sì, hai sbagliato. L'aggiunta di parentesi non modifica l'analisi di quell'espressione, il prefisso operator ++ restituisce un lvalue. L'UB è il risultato della scrittura sullo stesso lvalue due volte nello stesso punto di sequenza. –

+0

@Greg Rogers: Grazie! –

11

Sembra ovvio a voi, perché ovviamentei volontà primo essere assegnato i+1, poi secondo essere assegnato il valore 2.

Tuttavia, entrambe queste assegnazioni avvengono nello stesso punto sequenza, quindi è fino al compilatore per cui accade Frist e che avviene secondo, quindi diverse implementazioni compilatore possono generare il codice che darà risultati diversi, quindi è UB .

+4

Yeap e anche il compilatore non è richiesto per produrre lo stesso programma in diverse compilazioni. Stampa 0 su una compilazione, cancella il disco su un'altra. – sharptooth

1

La chiamata di ++i = 2; non comporta di per sé un comportamento non definito; qualsiasi compilatore può, se lo desidera, eseguire un'azione molto definita al raggiungimento di quel codice. Tuttavia lo standard C++ afferma che tale operazione non è definita, quindi un compilatore può fare qualcosa di inaspettato (come cancellare tutti i file sull'unità C o inviare un messaggio di testo al papa) ed essere comunque un compilatore conforme. L'unica cosa che rende questo UB è che lo standard dice che è UB.

Forse il punto più importante è che una versione di un compilatore può fare qualcosa di diverso dalla prossima versione dello stesso compilatore.

2

Il comportamento non definito si verifica perché un compilatore potrebbe implementare il seguente codice:

++i = 2; 

sia come:

i = 2; 
++i; 

o

++i; 
i = 2; 

E 'specificato nella lingua, un compilatore potrebbe scegliere di implementare uno dei precedenti. Il primo produrrebbe 3 e il secondo 2. Quindi è indefinito.

Problemi correlati