2010-05-29 15 views

Respuesta

83

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

Bjarne Stroustrup también dice explícitamente en "The C++ Programming Language" tercera sección de edición 6.2.2, con un poco de razonamiento:

código mejor se puede generar en el ausencia de restricciones sobre la expresión orden de evaluació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 también están definidos, es decir,

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

Puedo aceptar esta respuesta en 8 minutos ... ¡Creo que me estoy quedando un poco! –

+0

Sí, pero el mejor código podría escribirse (= limpiador) 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: http://stackoverflow.com/questions/43612592/the-case-where-c-abb-is-not-equal-to-c-abb-b-b1?noredirect=1#comment74274141_43612592 Así que hay , Stroustrup. –

+1

Si el pedido es importante, puede hacer la secuencia usted mismo. Hacer lo contrario siempre tendría un costo por algo que no siempre (¿raramente?) Importa. Creo que la política de no pagar por lo que no usas es lo único que acordaron la mayoría de los programadores de C++. – tweej

18

No hay un pedido especificado para bar() y baz(): lo único que el estándar dice es que ambos se evaluarán antes de llamar a foo(). Del estándar de C++, sección 5.2.2/8:

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

+2

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

13

Desde [5.2.2] La llamada a función,

El orden de evaluación de argumentos no se especifica. 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 ninguna garantía de que va a correr antes de bar()baz(), solo que bar() y baz() se llamará antes de foo.

También tenga en cuenta a partir de [5] Las expresiones que:

salvo donde se indique [por ejemplo, reglas especiales para && y ||], no se especifica 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.

por lo que incluso si se le pregunta si va a correr antes de bar()baz() en foo(bar() + baz()), el orden es todavía indeterminado.

+3

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

2

en C++ 11, el texto relevante puede encontrarse en 8.3.6 Default arguments/9 (énfasis mío)

argumentos predeterminados se evalúan cada vez que la función se llama. 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 verbosidad es también utilizada por el estándar C++ 14, y se encuentra en the same section.

0

Como ya se ha señalado, la norma no proporciona ninguna guía sobre el orden de evaluación para este escenario en particular. Este orden de evaluación se deja 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 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 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 allí. Tenga en cuenta que el compilador podría cambiar su metodología en el futuro

Cuestiones relacionadas