Se abbiamo tre funzioni (foo, bar e baz) che sono composte in questo modo ...
foo(bar(), baz())
C'è qualche garanzia dallo standard C ++ che la barra verrà valutata prima di baz?
Se abbiamo tre funzioni (foo, bar e baz) che sono composte in questo modo ...
foo(bar(), baz())
C'è qualche garanzia dallo standard C ++ che la barra verrà valutata prima di baz?
Risposte:
No, non esiste tale garanzia. Non è specificato secondo lo standard C ++.
Bjarne Stroustrup lo dice anche esplicitamente in "The C ++ Programming Language" 3a edizione sezione 6.2.2, con alcune ragioni:
È possibile generare codice migliore in assenza di restrizioni sull'ordine di valutazione dell'espressione
Sebbene tecnicamente questo si riferisca a una parte precedente della stessa sezione che dice che anche l'ordine di valutazione delle parti di un'espressione non è specificato, cioè
int x = f(2) + g(3); // unspecified whether f() or g() is called first
Da [5.2.2] Chiamata di funzione,
L'ordine di valutazione degli argomenti non è specificato. Tutti gli effetti collaterali delle valutazioni delle espressioni degli argomenti hanno effetto prima che la funzione venga inserita.
Pertanto, non vi è alcuna garanzia che bar()verrà eseguito prima baz(), solo quello bar()e baz()verrà chiamato prima foo.
Nota anche da [5] Expressions che:
tranne dove indicato [ad esempio regole speciali per
&&e||], l'ordine di valutazione degli operandi dei singoli operatori e delle sottoespressioni delle singole espressioni e l'ordine in cui si verificano gli effetti collaterali non è specificato.
quindi anche se stavi chiedendo se bar()verrà eseguito prima baz()in foo(bar() + baz()), l'ordine non è ancora specificato.
&, &&garantisce la valutazione da sinistra a destra: il secondo operando non viene valutato se il primo operando è false."
Non esiste un ordine specificato per bar () e baz () - l'unica cosa che lo Standard dice è che saranno entrambi valutati prima che venga chiamato foo (). Dallo standard C ++, sezione 5.2.2 / 8:
L'ordine di valutazione degli argomenti non è specificato.
bar, quindi la riga 1 di baz, quindi la riga 2 di bar, ecc.), Il che è anche bello. :-)
C ++ 17 specifica l'ordine di valutazione per gli operatori che non era specificato fino a C ++ 17. Vedere la domanda Quali sono le garanzie dell'ordine di valutazione introdotte da C ++ 17? Ma nota la tua espressione
foo(bar(), baz())
ha ancora un ordine di valutazione non specificato.
In C ++ 11, il testo pertinente può essere trovato in 8.3.6 Argomenti predefiniti / 9 (Enfasi mia)
Gli argomenti predefiniti vengono valutati ogni volta che viene chiamata la funzione. L'ordine di valutazione degli argomenti della funzione non è specificato . Di conseguenza, i parametri di una funzione non devono essere utilizzati in un argomento predefinito, anche se non vengono valutati.
La stessa verbosità è usata anche dallo standard C ++ 14 e si trova nella stessa sezione .
Come altri hanno già sottolineato, lo standard non fornisce alcuna guida sull'ordine di valutazione per questo particolare scenario. Questo ordine di valutazione viene quindi lasciato al compilatore e il compilatore potrebbe avere una garanzia.
È importante ricordare che lo standard C ++ è in realtà un linguaggio per istruire un compilatore sulla costruzione di codice assembly / macchina. Lo standard è solo una parte dell'equazione. Dove lo standard è ambiguo o è specificatamente definito dall'implementazione, dovresti rivolgerti al compilatore e capire come traduce le istruzioni C ++ in vero linguaggio macchina.
Quindi, se l'ordine di valutazione è un requisito, o almeno importante, e l'essere compatibili con i compilatori non è un requisito, cerca di capire come il tuo compilatore alla fine metterà insieme tutto questo, la tua risposta potrebbe essere lì. Nota che il compilatore potrebbe cambiare la sua metodologia in futuro