2012-06-13 20 views
14

¿El orden en el que se calculan los parámetros antes de que se llame un procedimiento definido en Delphi?En Delphi, ¿los parámetros se evalúan en orden cuando se pasan a un método?

OIA, si tengo este código feo (que se encuentra algo como esto en una aplicación heredada) ...

function A(var err: integer): integer; 
begin 
    err := 42; 
    Result := 17; 
end; 

Test(A(err), err); 

... es la prueba garantizada para recibir parámetros (17, 42) o podría también ser (17, indefinido)?


Editar:

Aunque el ejemplo de David devuelve un resultado diferente con 32 bits y 64 bits del compilador, este (por suerte) no afecta mi código heredado porque la prueba (A (err), err) solo almacena una dirección de 'err' en el registro y no importa si el compilador hace esto antes de llamar a A (err) o después.

+2

Este artículo puede ser de interés http://blog.barrkel.com/ 2008/04/c-evaluation-order-gotcha.html –

+1

Otra publicación sobre esto: http://stackoverflow.com/questions/3054526/delphi-compiler-directive-to-evaluate-arguments-in-reverse –

+0

@David, Era consciente de esta C 'característica' y aprendí en SO que Java y C# evalúan de izquierda a derecha, pero no podía recordar dónde ha documentado Delphi (y como hemos visto, la documentación es incorrecta). – gabr

Respuesta

12

El orden de la evaluación de parámetros en Delphi no está definido.

Como una interesante demostración de esto, el siguiente programa ha de salida diferente dependiendo de si usted apunta código de 32 o 64 bits:

program ParameterEvaluationOrder; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

function SideEffect(A: Integer): Integer; 
begin 
    Writeln(A); 
    Result := A; 
end; 

procedure Test(A, B: Integer); 
begin 
end; 

begin 
    Test(SideEffect(1), SideEffect(2)); 
    Readln; 
end. 
+0

En Win64, el orden de evaluación está definido por la única convención de llamadas, AFAIK. En Win32, existen diferentes convenciones de llamadas, y no especifican el orden de evaluación, solo el orden de aprobación. –

+4

@RudyVelthuis Según mi leal saber y entender, las convenciones de llamadas especifican el orden de * pasar * pero no especifican el orden de * evaluación *. Así que no estoy de acuerdo con ese comentario. –

+0

IMO, las convenciones de llamada pueden especificar lo que quieran, funciones de llamada WRT. Si también se especifica el orden de evaluación, por la razón que sea el desarrollador de la plataforma, es mejor que siga las especificaciones. Pero estoy de acuerdo en que, AFAIK, hasta ahora, ninguna convención de llamadas ha hecho esto. –

5

Editado: parece que el compilador puede violar el comportamiento descrito en la ayuda:

De Calling Conventions tema de ayuda (el énfasis es mío): convenciones

el registro y pascal pasan parámetros de de izquierda a derecha; es decir, el parámetro más a la izquierda es evaluado y pasado primero y el parámetro más a la derecha se evalúa y se pasa el último.

+0

Resulta que la documentación que enlaza es incorrecta. –

+0

me entristece que el comportamiento del compilador no corresponda a la única fuente de documentación oficial – MBo

+0

Estoy de acuerdo. Personalmente creo que está bien que la orden de evaluación no esté definida, pero la documentación no debe indicar lo contrario. –

Cuestiones relacionadas