2013-06-18 10 views
11

Non riesco a trovare una risposta definitiva per questo: il seguente codice ha un comportamento non definito?Assegnazioni multiple di composti in una singola istruzione: si tratta di comportamento non definito o no?

int x = 2; 
x+=x+=x+=2.5; 
+0

Questo * non * è un duplicato. Qui l'espressione è 'x + = (x + = 10)', che è diverso da '(x + = 10) + = 10' - il comportamento qui è indefinito dove l'altra domanda non lo è (in C++ 11). – interjay

+0

Il mio commento sopra si riferisce alla domanda [In quali versioni dello standard C++ fa "(i + = 10) + = 10" ha un comportamento indefinito?] (Http://stackoverflow.com/questions/10655290/in-which-versions -of-the-c-standard-does-i-10-10-have-undefined-behaviou) che è stato precedentemente contrassegnato come duplicato. – interjay

+0

perché vuoi davvero saperlo? – Alex

risposta

14

Il comportamento non è definito. Guardiamo l'espressione un po 'più semplice:

x += (x+=1) 

In C++ 11, il valore del calcolo lasciato il x è non in sequenza rispetto al valore di calcolo dell'espressione (x+=1). Ciò significa che il calcolo del valore di x non viene eseguito in relazione all'assegnazione a x (a causa di x+=1) e pertanto il comportamento non è definito.

La ragione di ciò è che il calcolo del valore dei due lati dell'operatore += non è correlato l'uno all'altro (poiché lo standard non specifica diversamente). E 1.9p15 stati:

Se un effetto collaterale su un oggetto scalare è non in sequenza rispetto a uno altro effetto collaterale sullo stesso oggetto scalare o un calcolo valore utilizzando il valore dello stesso oggetto scalare, il comportamento è indefinito.

In C++ 03 il comportamento non è definito perché x viene modificato due volte senza un punto di sequenza intermedio.

+2

Nota: se 'x' fosse un oggetto, con un operatore' definito dall'utente + = ', allora sarebbe definito ... –

+0

Ci scusiamo per aver prima fatto down-down di questo. Come hai spiegato nel tuo commento sulla domanda, le due espressioni sono diverse e infatti la tua risposta è completamente corretta. +1 –

0

Per le virgolette standard vedere le altre risposte. In questo caso è probabile trovare uno dei due comportamenti diversi.

x += (x += 2); 

Può essere sia

x = 2 + 4 (= 6) 

se il valore di x sul lato sinistro viene valutata prima x+=2 o

x = 4 + 4 (= 8) 

se il valore di x per l'operatore sinistra viene determinata in seguito.


operativa -Editazione-

so che Not Gonna Get molti fan su SO se dico che non mi piace chi "tutto può accadere" affermazioni molto. È vero che qualsiasi compilatore può dichiararsi conforme allo standard indipendentemente da come viene gestita la dichiarazione qui discussa rispetto al valore di x. Tuttavia, penso che ciò non significhi che l'operatore + = possa portare a un risultato errato o che le parate possano essere ignorate. Il comportamento non definito non è lo stesso del comportamento non definito in qualsiasi altro caso.

È cattiva schiena su qualsiasi affidamento sul comportamento indefinito ma nell'esempio sopra i vedere buoni motivi trascurare alcun risultato possibile ma 6 e 8.

Inoltre ho effettivamente sospettato di essere x 8 dopo la valutazione di int x=2; x += (x += 2); per la maggior parte dei compilatori stabiliti (clang, g ++, vc, icpc ...).

Si deve ripetere che non si deve fare affidamento su un comportamento del genere ma ciò non significa che sia completamente imprevedibile.

+4

** Qui possono verificarsi almeno ** due comportamenti. Il comportamento non è definito, quindi enumerare possibili comportamenti è un compito senza fine. –

+0

c'è una differenza tra mostrare che esistono almeno due risultati diversi (mostrati per contraddizione) per enumerare. Per il caso 2 questi sono identici. – Alex

+1

L'ottimizzazione dei compilatori può * presupporre * che il comportamento del programma non sia indefinito. Se violate questa ipotesi, possono eseguire trasformazioni che violano * le vostre * ipotesi. In ogni caso, non dovrebbe davvero importare come 'x + = (x + = 2);' si comporta; qualunque cosa voglia dire, c'è un modo più chiaro per esprimerlo. –

Problemi correlati