Si tenemos tres funciones (foo, bar y baz) que están compuestas así ...
foo(bar(), baz())
¿Existe alguna garantía por parte del estándar C ++ de que la barra se evaluará antes que baz?
Si tenemos tres funciones (foo, bar y baz) que están compuestas así ...
foo(bar(), baz())
¿Existe alguna garantía por parte del estándar C ++ de que la barra se evaluará antes que baz?
Respuestas:
No, no existe tal garantía. No está especificado según el estándar C ++.
Bjarne Stroustrup también lo dice explícitamente en "El lenguaje de programación C ++" sección 6.2.2 de la tercera edición, con algún razonamiento:
Se puede generar un mejor código en ausencia de restricciones en el orden de evaluación de expresiones
Aunque técnicamente esto se refiere a una parte anterior de la misma sección que dice que el orden de evaluación de las partes de una expresión tampoco está especificado, es decir
int x = f(2) + g(3); // unspecified whether f() or g() is called first
Desde [5.2.2] Llamada a función,
El orden de evaluación de los argumentos no se especifica. Todos los efectos secundarios de las evaluaciones de expresiones de argumentos entran en vigor antes de que se ingrese la función.
Por lo tanto, no hay garantía de que bar()
se ejecutará antes baz()
, solo eso bar()
y baz()
se llamará antes foo
.
También tenga en cuenta de [5] Expresiones que:
excepto donde se indique [por ejemplo, reglas especiales para
&&
y||
], el orden de evaluación de los operandos de operadores individuales y subexpresiones de expresiones individuales, y el orden en el que se producen los efectos secundarios, no se especifica.
por lo que incluso si preguntaba si bar()
se ejecutará antes baz()
en foo(bar() + baz())
, el orden aún no está especificado.
&
, &&
garantiza la evaluación de izquierda a derecha: el segundo operando no se evalúa si el primer operando lo es false
".
No hay un orden específico para bar () y baz (); lo único que dice el Estándar es que ambos serán evaluados antes de que se llame a foo (). Del estándar C ++, sección 5.2.2 / 8:
El orden de evaluación de los argumentos no se especifica.
bar
, luego la línea 1 de baz
, luego la línea 2 de bar
, etc.), lo cual también es bueno. :-)
C ++ 17 especifica el orden de evaluación para los operadores que no se especificó hasta C ++ 17. Vea la pregunta ¿Cuáles son las garantías de orden de evaluación introducidas por C ++ 17? Pero fíjate en tu expresión
foo(bar(), baz())
todavía tiene un orden de evaluación sin especificar.
En C ++ 11, el texto relevante se puede encontrar en 8.3.6 Argumentos predeterminados / 9 (énfasis mío)
Los argumentos predeterminados se evalúan cada vez que se llama a la función. El orden de evaluación de los argumentos de la función no está especificado . En consecuencia, los parámetros de una función no se utilizarán en un argumento predeterminado, incluso si no se evalúan.
El estándar C ++ 14 también usa la misma verborrea, y se encuentra en la misma sección .
Como ya han señalado otros, la norma no proporciona ninguna orientación sobre el orden de evaluación para este escenario en particular. Este orden de evaluación se deja entonces al compilador, y el compilador puede tener una garantía.
Es importante recordar que el estándar C ++ es realmente un lenguaje para instruir a un compilador en la construcción de código ensamblador / máquina. El estándar es solo una parte de la ecuación. Cuando el estándar sea ambiguo o esté específicamente definido por la implementación, debe recurrir al compilador y comprender cómo traduce las instrucciones de C ++ al verdadero lenguaje de máquina.
Por lo tanto, si el orden de evaluación es un requisito, o al menos importante, y ser compatible con el compilador cruzado no es un requisito, investigue cómo su compilador finalmente ensamblará esto, su respuesta podría estar ahí. Tenga en cuenta que el compilador podría cambiar su metodología en el futuro