Sì, questo è coperto dallo standard ed è il comportamento specificato. Questo caso particolare è coperto da una recente proposta di standard C++: N4228: Refining Expression Evaluation Order for Idiomatic C++ che cerca di perfezionare l'ordine delle regole di valutazione per renderlo ben specificato in determinati casi.
Esso descrive il problema come segue:
ordine di valutazione di espressione è un argomento di discussione ricorrente nella comunità di C++ . In breve, data un'espressione come f (a, b, c), l'ordine in cui vengono valutate le sottoespressioni f, a, b, c non viene specificato dallo standard. Se due di queste sotto-espressioni capita di modificare lo stesso oggetto senza punti di sequenza intermedi, il comportamento del programma non è definito. Ad esempio, l'espressione f (i ++, i) dove i è una variabile porta a comportamento non definito, così come v [i] = i ++. Anche quando il comportamento non è indefinito, il risultato della valutazione di un'espressione può ancora essere indovinato da chiunque. Si consideri il seguente frammento di programma:
#include <map>
int main() {
std::map<int, int> m;
m[0] = m.size(); // #1
}
Quale dovrebbe essere la carta oggetto m simile dopo la valutazione della dichiarazione segnato 1 #? {{0, 0}} o {{0, 1}}?
Noi sappiamo che se non specificato le valutazioni dei sub-espressioni sono non in sequenza, questo è dal draft C++11 standard sezione 1.9
esecuzione programma che dice:
Salvo quando diversamente indicato, valutazioni di operandi dei singoli operatori e di sottoespressioni delle singole espressioni sono non in sequenza. [...]
e tutta la sezione 0.123.138,087856 millionsassegnazione e assegnazione composto operatori [expr.ass] dice è:
[...] In tutti i casi, l'assegnazione viene sequenziato dopo che il valore calcolo degli operandi destra e sinistra, e prima che il calcolo del valore dell'espressione di assegnazione. [...]
Quindi questa sezione non inchiodare giù l'ordine di valutazione, ma sappiamo che questo non è un comportamento indefinito in quanto sia operator []
e size()
sono chiamate di funzione e la sezione 1.9
ci dice (emphasis mine):
[...] Quando si chiama una funzione (se la funzione è in linea), ogni valore calcolo e lato effetto associato con qualsiasi espressione argomentazione, o con l'espressione suffisso designa la funzione chiamata, è sequenziata prima dell'esecuzione di ogni espressione o affermazione nel corpo della funzione chiamata.[Nota: i calcoli del valore e gli effetti collaterali associati alle diverse espressioni degli argomenti non sono seguiti. -end note] Ogni valutazione nella funzione chiamante (comprese altre chiamate di funzione) che non sia specificatamente sequenziata prima o dopo l'esecuzione del corpo della funzione chiamata viene indeterminatamente sequenziata con rispetto all'esecuzione della funzione chiamata 0,9 [...]
nota, copro il secondo esempio interessante dal N4228
proposta in tal question here.
Aggiornamento
sembra una versione rivista del N4228
era accepted by the Evolution Working Group at the last WG21 meeting ma la carta (P0145R0) non è ancora disponibile. Quindi questo potrebbe non essere più specificato in C++ 17.
Questo è davvero curioso. gcc 4.8.4 restituisce anche 0 1, ma clang 3.4 restituisce 0 0. – Harald
Si dovrebbe fare attenzione con la parola "undefined". Non è sinonimo di "non specificato". – molbdnilo
E per aggiungere alla dichiarazione di Redcrash, gcc 4.9.2 e clang 3.8 di venerdì sera seguono entrambi i risultati 4.8.4 e 3.4. Rafforzando ulteriormente che non vi è alcun obbligo da qualche parte per avere un ordine specifico per questo. –