9

Ho avuto il mio cervello rugosa dal cercare di capire gli esempi in questa pagina: http://answers.yahoo.com/question/index?qid=20091103170907AAxXYG9In che modo l'ordine di valutazione delle espressioni differisce tra C++ e Java?

In particolare questo codice:

int j = 4; 
cout << j++ << j << ++j << endl; 

dà una potenza: 566

Ora questo ha un senso per me se l'espressione viene valutata da destra a sinistra, tuttavia in Java un'espressione simile:

int j = 4; 
System.out.print("" + (j++) + (j) + (++j)); 

fornisce un'uscita di: 456

Quale è più intuitivo perché indica che è stato valutato da sinistra a destra. Facendo una ricerca su vari siti, sembra che con C++ il comportamento differisca tra i compilatori, ma non sono ancora convinto di aver capito. Qual è la spiegazione di questa differenza di valutazione tra Java e C++? Grazie COSÌ.

+2

Tutto è diverso. Non è solo diverso tra i compilatori, è _against the rules_, e può cambiare ogni volta che si compila sullo stesso compilatore, ogni volta che si esegue il programma, o anche ogni volta che viene eseguita la riga. –

+0

possibile duplicato di [In che modo undefined è un comportamento indefinito?] (Http://stackoverflow.com/questions/7961067/how-undefined-is-undefined-behavior) –

+1

C++ è progettato per essere ottimizzato, il che significa che lo standard non garantire certi risultati in modo che il compilatore sia libero di generare codice ottimale. La sequenza che usi nel tuo esempio è una che credo sia specificamente vietata. –

risposta

11

Quando un'operazione ha effetti collaterali, C++ si affida alla regola sequence points per decidere quando gli effetti collaterali (come incrementi, assegnazioni combinate, ecc.) Devono avere effetto. Logico and-then/or-else (&& e ||) operatori, ternario ? operatori punto interrogativo e virgole creano punti di sequenza; +, -, << e così via no.

Al contrario, Java completa gli effetti collaterali prima di procedere con un'ulteriore valutazione.

Quando si utilizza un'espressione con effetti collaterali più volte in assenza di punti di sequenza, il comportamento risultante non è definito in C++. Qualsiasi risultato è possibile, incluso uno che non ha senso logico.

3

In C++ l'ordine di valutazione delle sottoespressioni non è da sinistra a destra né da destra a sinistra. È non definito.

5

Java garantisce che gli operandi degli operatori sembrano essere valutati in un ordine di valutazione specifico, vale a dire, da sinistra a destra. L'operando di sinistra di un operatore binario sembra essere completamente valutato prima di valutare qualsiasi parte dell'operando di destra. Java garantisce inoltre che ogni operando di un operatore (eccetto gli operatori condizionali , || e ?:) sembra essere completamente valutato prima di eseguire qualsiasi parte dell'operazione stessa. Vedi le specifiche del linguaggio Java §15.7 per maggiori dettagli.

C++, d'altra parte, felicemente lasciatevi andare con un comportamento indefinito se l'espressione è ambigua perché il linguaggio stesso non garantisce alcun ordine di valutazione delle sottoespressioni. Vedi Sequence Point per maggiori dettagli.

Problemi correlati