2011-11-28 18 views
8
int& foo() { 
    printf("Foo\n"); 
    static int a; 
    return a; 
} 

int bar() { 
    printf("Bar\n"); 
    return 1; 
} 

void main() { 
    foo() = bar(); 
} 

Non sono sicuro quale debba essere valutato per primo.Ordine di valutazione funzione C++ nell'operatore di assegnazione

Ho provato in VC che la funzione di barra viene eseguita per prima. Tuttavia, nel compilatore di g ++ (FreeBSD), emette prima la funzione foo valutata.

Molto domanda interessante deriva dal problema di cui sopra, supponiamo di avere una matrice dinamica (std :: vector)

std::vector<int> vec; 

int foobar() { 
    vec.resize(vec.size() + 1); 
    return vec.size(); 
} 

void main() { 
    vec.resize(2); 
    vec[0] = foobar(); 
} 

Sulla base del risultato precedente, il VC valuta l'pippo() e quindi eseguire il vettore operatore[]. Non è un problema in questo caso. Tuttavia, per gcc, poiché il vec [0] è in fase di valutazione e la funzione foobar() può portare a modificare il puntatore interno dell'array. Il vec [0] può essere invalidato dopo l'esecuzione di foobar().

E 'significa che abbiamo bisogno di separare il codice in modo che

void main() { 
    vec.resize(2); 
    int a = foobar(); 
    vec[0] = a; 
} 
+3

+2, questa è una domanda interessante; è qualcosa che non ho mai considerato prima. Ovviamente sei nei guai se inizi ad usare un codice del genere comunque :) –

+0

+1. È davvero una domanda interessante; più che la domanda è posta molto bene. Una domanda ben scritta. – Nawaz

+1

Mi sono imbattuto in un interessante esempio di questo oggi: 'auto_ptr p (nuovo int); smart_map m; m [1] = p.release(); 'Se si suppone che' smart_map :: operator [] 'possa lanciare, si potrebbe avere un caso in cui' auto_ptr' ne rilascia la proprietà ma la mappa non assume mai la proprietà, nel caso in cui l'RHS viene valutato prima del LHS. (Supponiamo che 'smart_map' sia come una' map' STL, tranne che cancella il valore del puntatore di ogni coppia chiave/valore alla distruzione.) – mrkj

risposta

8

Ordine di valutazione sarebbe non specificato in questo caso. Dont write tale codice

esempio simile here

0

Ordine di valutazione di un'espressione è specificato Comportamento.
Dipende dal compilatore quale ordine sceglie di valutare.

Si dovrebbe astenersi dal scrivere codici shuch.
Anche se non ci sono effetti collaterali, l'ordine non dovrebbe avere importanza.

Se le questioni di ordine, quindi il codice è sbagliato /Non portatile/può dare risultati diversi attraversato diversi compilatori **.

5

Il concetto in C++ che determina se l'ordine di valutazione è definito è denominato sequence point.

Fondamentalmente, in un punto di sequenza, è garantito che tutte le espressioni precedenti a quel punto (con effetti collaterali osservabili) sono state valutate e che nessuna espressione oltre quel punto è stata ancora valutata.

Anche se alcuni potrebbero trovarlo sorprendente, l'operatore di assegnazione non è un punto di sequenza. Un elenco completo di tutti i punti di sequenza si trova nello Wikipedia article.

+2

... _was_ ha chiamato il punto di sequenza. Da quest'anno usiamo _sequenced before_/_sequenced after_. – MSalters

+0

@MSalters: Grazie per avermelo fatto notare - non ne ero consapevole! –

Problemi correlati