2015-03-28 7 views
6

Non riesco ancora a capire se l'espressione x ^= y ^= x ^= y; valida in C++ 11 (come si dice in questo thread) o che porti a un comportamento non definito?Scambia gli interi tramite XOR in una riga singola. È davvero permesso in C++ 11?

Le ragioni addotte dal collegamento sembrano convincenti, ma clang getta un warning:

avvertimento: la modifica non in sequenza e l'accesso a 'x' [-Wunsequenced]

Del resto, se entrambe le versioni :

x ^= y ^= x ^= y; // (1) 
x = x^(y = y^(x = (x^y))); // (2) 

considerato equivalente (e ben definito in C++ 11), perché dà risultati diversi (first, second)?

Inoltre, si noti che gcc fornisce un warning sul punto di sequenza solo sulla seconda versione del codice.

+2

No, non è ben definito. L'analisi è molto simile a quella di 'i + = ++ i + 1' in [questa domanda] (http://stackoverflow.com/questions/24194076/in-c11-does-ii-1-exhibit-undefined- comportamento). –

+0

quelle versioni non sono affatto equivalenti. – UmNyobe

+1

Vedere http://stackoverflow.com/questions/29313902/sequence-point-within-assignment-operators – Lingxi

risposta

11

L'operatore di assegnazione (=) e gli operatori di assegnazione composto tutto il gruppo da destra a sinistra. [..] Il comportamento di un'espressione del modulo E1 op = E2 equivale a E1 = E1 op E2 eccetto che E1 è valutato una sola volta.

Così il codice è equivalente a

x = x^(y ^= (x ^= y))); 

... con x valutata solo una volta in x = x .... Sfortunatamente, per xor, la valutazione degli operandi non viene eseguita. Cioè

Tranne dove indicato, le valutazioni degli operandi dei singoli operatori e delle sottoespressioni delle singole espressioni sono state annullate.

. Ma ora abbiamo un problema:

x = x^(y ^= (x ^= y))); 
//  *   ****** 
//  |   | 
//  |   Side effect 
//  Value computation 

Il valore di calcolo (che è implicito al singolare valutazione x per i due più a sinistra x) e l'effetto collaterale sono wrt non in sequenza tra loro, quindi abbiamo indurre UB:

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

+1

ma ancora non risponde se la prima versione è UB o no – sp2danny

+0

@ sp2danny Hai letto la mia risposta? – Columbo

+0

im iniziando a inclinarsi verso entrambi i costrutti essendo UB – sp2danny

Problemi correlati