Orden de evaluación en parámetros de función C ++

Si tenemos tres funciones (foo, bar y baz) que están compuestas así …

foo(bar(), baz()) 

¿Hay alguna garantía en el estándar C ++ de que la barra se evalúe antes de baz?

No, no hay tal garantía. No está definido de acuerdo con el estándar C ++.

Bjarne Stroustrup también lo dice explícitamente en “The C ++ Programming Language”, tercera edición de la sección 6.2.2, con algún razonamiento:

Se puede generar un código mejor en ausencia de restricciones en el orden de evaluación de expresión

Aunque técnicamente esto se refiere a una parte anterior de la misma sección que dice que el orden de evaluación de partes de una expresión tampoco está definido, es decir,

 int x = f(2) + g(3); // undefined whether f() or g() is called first 

No hay un orden específico para bar () y baz (): lo único que el estándar dice es que ambos serán evaluados antes de llamar a foo (). Del estándar C ++, sección 5.2.2 / 8:

El orden de evaluación de los argumentos no está especificado.

Desde [5.2.2] Llamada de función,

El orden de evaluación de los argumentos no está especificado. Todos los efectos secundarios de las evaluaciones de expresión de argumentos surten efecto antes de que se ingrese la función.

Por lo tanto, no hay garantía de que bar() se ejecute antes de baz() , solo que se llamará a bar() y baz() antes de 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 operandos de operadores individuales y subexpresiones de expresiones individuales, y el orden en que se producen los efectos secundarios, no se especifica.

por lo tanto, incluso si estuviera preguntando si bar() se ejecutará antes de baz() en foo(bar() + baz()) , el orden aún no está especificado.

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 note su expresión

 foo(bar(), baz()) 

todavía tiene un orden de evaluación no especificado.

En C ++ 11, el texto relevante se puede encontrar en 8.3.6 Argumentos por defecto / 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.

La misma verborrea también se utiliza en el estándar C ++ 14, y se encuentra en la misma sección .

Como otros ya han señalado, la norma no proporciona ninguna guía sobre el orden de evaluación para este escenario particular. Este orden de evaluación se deja al comstackdor y el comstackdor puede tener una garantía.

Es importante recordar que el estándar C ++ es realmente un lenguaje para instruir a un comstackdor sobre la construcción de código ensamblador / máquina. El estándar es solo una parte de la ecuación. Cuando el estándar es ambiguo o está específicamente definido como implementación, debe consultar el comstackdor 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 comstackdor cruzado no es un requisito, investigue cómo su comstackdor finalmente ensamblará esto, su respuesta podría estar allí. Tenga en cuenta que el comstackdor podría cambiar su metodología en el futuro