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

5 minutos de lectura

Si tenemos tres funciones (foo, bar y baz) que se componen así…

foo(bar(), baz())

¿Existe alguna garantía por parte del estándar C++ de que la barra se evaluará antes que la baz?

Orden de evaluacion en los parametros de funcion de C
Eli Bendersky

No, no hay tal garantía. No está especificado según el estándar C++.

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

Se puede generar 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

  • Sí, pero se podría ESCRIBIR un código mejor (= más limpio) si el orden de evaluación de la expresión fuera ESTRICTO, que generalmente es mucho más importante que la generación de código. Vea este ejemplo: stackoverflow.com/questions/43612592/… Entonces, Stroustrup.

    – Bill Kotsias

    25 de abril de 2017 a las 13:57


  • Si el orden es importante, puede hacer la secuencia usted mismo. De lo contrario, siempre incurriría en un costo por algo que no siempre (¿rara vez?) Importa. Creo que la política de no pagar por lo que no usas es lo único en lo que la mayoría de los programadores de C++ están de acuerdo.

    – tweej

    2 de diciembre de 2017 a las 9:53

  • ¿No debería ser “comportamiento no especificado” en lugar de “indefinido”?

    – Buenas acciones

    6 de enero de 2018 a las 19:38

  • @GoodDeeds Anterior C ++ 17, comportamiento indefinido si las funciones causan efectos secundarios en la misma ubicación de memoria. Publicar C ++ 17 no está especificado.

    – Transeúnte

    22 de junio de 2018 a las 16:53

  • @ChrisDodd rechazar una respuesta aceptada debido al uso de la palabra “indefinido” frente a “no especificado” me parece una pedantería maliciosa … No dije que esto es un “comportamiento indefinido”, y de lo contrario parece “indefinido” y “no especificado” ¿sinónimo? En cualquier caso, proponer una edición de la respuesta habría sido una forma más productiva de discutir esto

    – Eli Bendersky

    20 de julio de 2018 a las 13:19

1647548887 985 Orden de evaluacion en los parametros de funcion de C
daniel trebbin

Desde [5.2.2] Llamada de función,

No se especifica el orden de evaluación de los argumentos. Todos los efectos secundarios de las evaluaciones de expresiones de argumento surten efecto antes de que se ingrese la función.

Por lo tanto, no hay garantía de que bar() correrá antes baz()sólo eso bar() y baz() será llamado antes foo.

También nota de [5] Expresiones que:

excepto donde se indique [e.g. special rules for && and ||]no se especifica el orden de evaluación de los operandos de los operadores individuales y las subexpresiones de las expresiones individuales, ni el orden en que se producen los efectos secundarios.

así que incluso si estuvieras preguntando si bar() correrá antes baz() en foo(bar() + baz())el orden aún no está especificado.

  • Un ejemplo de una “nota especial” de [5.14] Operador lógico AND: “A diferencia de &, && garantiza la evaluación de izquierda a derecha: el segundo operando no se evalúa si el primer operando es false.”

    – Daniel Trebbien

    29 de mayo de 2010 a las 12:31

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:

No se especifica el orden de evaluación de los argumentos.

  • El hecho de que se evalúen antes que foo() es un poco tranquilizador, al menos.

    – Bill Kotsias

    25 de abril de 2017 a las 13:58

  • @BillKotsias El estándar también dice que las llamadas a funciones no se pueden superponer (es decir, una implementación no puede ejecutar la línea 1 de barentonces la línea 1 de bazentonces la línea 2 de bar, etc.), que también es agradable. 🙂

    – melpomene

    31 de julio de 2019 a las 21:04

C++17 especifica el orden de evaluación de los operadores que no se especificaba hasta C++17. Consulte la pregunta ¿Cuáles son las garantías de orden de evaluación introducidas por C++17? Pero nota tu 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 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 palabrería, y se encuentra en la misma sección.

Orden de evaluacion en los parametros de funcion de C
Programador erudito

Como ya han señalado otros, el estándar no brinda ninguna orientación sobre el orden de evaluación para este escenario en particular. Este orden de evaluación se deja luego 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 sólo una parte de la ecuación. Cuando el estándar es ambiguo o está específicamente definido por la implementación, debe recurrir al compilador y comprender cómo traduce las instrucciones de C++ a un verdadero lenguaje de máquina.

Entonces, si el orden de evaluación es un requisito, o al menos importante, y la compatibilidad entre compiladores no es un requisito, investigue cómo su compilador finalmente ensamblará esto, su respuesta finalmente podría estar allí. Tenga en cuenta que el compilador podría cambiar su metodología en el futuro

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad