2009-11-07 13 views
9

ho letto su 'effetto collaterale' dal this website:perché "f = f ++" non è sicuro in c?

ma ancora non capisco perché f = f++ considerato pericoloso?

Qualcuno può spiegare?

+0

duplicati (anche se non proprio ovvia se non lo fai conoscere la risposta perché) http://stackoverflow.com/questions/1678519/difference- between-i-and-i –

+1

C'è anche una domanda da qualche parte sul perché "++ i ++" è illegale ma è impossibile cercarlo! –

+3

Questa domanda chiede esplicitamente perché questo costrutto non è sicuro.La domanda a cui fai riferimento ha codice che non è valido _because_ questo costrutto non è sicuro. Due diverse domande completamente valide. – joshperry

risposta

16

Il problema è Sequence Points. Ci sono due operazioni in questa statistica senza punto di sequenza, quindi non c'è un ordine definito per la dichiarazione, l'assegnazione avviene prima o l'incremento?

Nulla dice che è pericoloso, è solo indefinito, il che significa che diverse implementazioni possono avere risultati diversi o può formattare il disco rigido ...

+2

Penso che molte persone considererebbero la formattazione di un disco una conseguenza non sicura di 'f = f ++'. Anche se penso che la maggior parte della gente dice 'non sicuro' non intendendo che possa distruggere qualcosa, ma che non si può dipendere da ciò che farà. –

+0

Lo standard C e C++ utilizza in modo esplicito il termine "comportamento indefinito" in tutto, e in particolare nella sezione che dettaglia l'ordine di esecuzione del punto di sequenza. Stavo semplicemente usando l'iperbole per accentuare la differenza tra non sicuro e non definito. – joshperry

+4

un comportamento non sicuro implica codice non sicuro – hasen

4

Utilizzando x e x++ (o ++x) all'interno della stessa istruzione è comportamento non definito in C. Il compilatore è libero di fare ciò che vuole: o incrementare x prima di eseguire il compito, o dopo. Prendendo il codice di Ólafur, potrebbe produrre f == 5 o f == 6, a seconda del compilatore.

4

L'articolo al numero (cleaned up) link fornito fornisce la risposta. "C fa quasi nessuna promessa che gli effetti collaterali si verifichino in un ordine prevedibile all'interno di una singola espressione." Ciò significa che non sai in quale ordine si verificherà = e il ++. È dipendente dal compilatore.

Se si segue il collegamento da questo articolo all'articolo sequence points sullo stesso sito, si vedrà che il compilatore può ottimizzare cosa e quando scrive i valori dai registri nelle variabili.

+0

Un ulteriore bit di chiarificazione: non dipende solo dal compilatore. Ciò che il compilatore può fare potrebbe non avere alcun senso - anche al punto che 2 istanze della stessa istruzione (con lo stesso valore di partenza per 'f') potrebbero produrre risultati completamente diversi. –

0

Sostengo la risposta di Arthur a questo riguardo. Sebbene l'implementazione dell'operatore di post-incremento i.e f ++ sia confusa, non è considerata non sicura. U dovrebbe prima capire come il compilatore lo interpreta. se aumenterà f dopo aver rilevato una terminazione di frase (;) o immediatamente dopo aver usato il valore di f.

+1

È * non definito *, nel senso dello standard C. Questo non è il caso di "devi sapere cosa fa il compilatore". Il compilatore può fare qualsiasi cosa, incluso dare un valore a f che non corrisponde ad alcuno degli ordini delle istruzioni atomiche che si pensa debba generare. –

1

Dal standard

6,5 (2) Se un effetto collaterale su un oggetto scalare è non in sequenza relativa sia ad un diverso effetto collaterale sullo stesso oggetto scalare o un calcolo valore utilizzando il valore dello stesso scalari oggetto, il comportamento non è definito. Se esistono più ordinamenti consentiti delle sottoespressioni di un'espressione, il comportamento non è definito se un effetto di questo tipo lato non eseguito si verifica in uno degli ordini. 74)

74) Questo paragrafo rende espressioni dichiarazione non definite, come

 
      i = ++i + 1; 
      a[i++] = i; 

consentendo

 
      i = i + 1; 
      a[i] = i;