2012-09-22 9 views
9

La norma non specifica l'ordine di valutazione degli argomenti con questa linea:Perché l'ordine di valutazione per i parametri di funzione non è specificato in C++?

L'ordine di valutazione degli argomenti non è specificato.

Cosa significa

Meglio codice può essere generata in assenza di restrizioni al fine di valutazione espressione

implica?

Qual è lo svantaggio nel chiedere a tutti i compilatori di valutare gli argomenti della funzione Da sinistra a destra, ad esempio? Quali tipi di ottimizzazioni eseguono i compilatori a causa di questa specifica non specificata?

+4

Permettere al compilatore di riordinare la valutazione degli operandi aggiunge più spazio per l'ottimizzazione. – Mysticial

+1

@Mysticial: Assurdo come potrebbe sembrare, dovrebbe essere una risposta, e in realtà la risposta * accettata *! –

+0

Quali tipi di ottimizzazioni eseguono i compilatori? – unj2

risposta

25

Permettere al compilatore di riordinare la valutazione degli operandi offre più spazio per l'ottimizzazione.

Ecco un esempio completamente inventato a scopo illustrativo.

Supponiamo che il processore può:

  • Edizione 1 istruzione ogni ciclo.
  • Eseguire un'aggiunta in 1 ciclo.
  • Esegui una moltiplicazione in 3 cicli.
  • Può eseguire aggiunte e moltiplicazioni allo stesso tempo.

Ora si supponga di avere una chiamata di funzione come segue:

foo(a += 1, b += 2, c += 3, d *= 10); 

Se si dovesse eseguire questo da sinistra a destra su un processore senza OOE:

Cycle - Operation 
0  - a += 1 
1  - b += 2 
2  - c += 3 
3  - d *= 10 
4  - d *= 10 
5  - d *= 10 

Ora, se si consentire al compilatore di riordinarli: (e avviare prima la moltiplicazione)

Cycle - Operation 
0  - d *= 10 
1  - a += 1, d *= 10 
2  - b += 2, d *= 10 
3  - c += 3 

Quindi 6 cicli contro 4 cicli.

Ancora una volta questo è completamente inventato. I processori moderni sono molto più complicati di così. Ma tu hai l'idea.

1

Ecco un semplice esempio. Supponiamo di avere una chiamata di funzione come segue:

// assume that p is a pointer to an integer 
foo(*p * 3, bar(), *p * 3 + 1); 

Il compilatore ha bisogno di dereference p due volte (e fare un po calcoli sulla base del risultato) e chiamare bar una volta. Se il compilatore è intelligente, potrebbe riordinare la valutazione di

int temp = *p * 3; 
foo(temp, bar(), temp + 1); 

In questo modo si ha a che fare il "dereferenziare, moltiplicare per 3" solo una volta. Questo è noto come eliminazione di sottoespressione comune.

+1

Per essere giusti, anche i linguaggi che garantiscono l'ordine di valutazione possono farlo, a condizione che siano in grado di dimostrare che il valore di 'p' non può cambiare in mezzo. Naturalmente, con il modello di memoria C che è praticamente impossibile da garantire, che è probabilmente il motivo per cui è necessario un ordine di valutazione non definito per ottenere questa ottimizzazione. – Joey

Problemi correlati