2012-06-13 15 views
14

L'ordine in cui i parametri vengono calcolati prima che una procedura venga definita in Delphi?In Delphi, i parametri vengono valutati in ordine quando vengono passati a un metodo?

IOW, se ho questo codice brutto (trovato qualcosa di simile in un'applicazione legacy) ...

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

Test(A(err), err); 

... è Test garantito per ricevere i parametri (17, 42) o potrebbe anche essere (17, non definito)?


Edit:

Anche se l'esempio di David torna risultato diverso con 32-bit e 64-bit compilatore, questo (per fortuna) non influenza il mio codice legacy a causa di prova (A (err), err) solo negozi un indirizzo di "err" nel registro e non importa se il compilatore lo fa prima di chiamare A (err) o dopo.

+2

Questo articolo può essere di interesse http://blog.barrkel.com/ 2008/04/c-evaluation-order-gotcha.html –

+1

Un altro post su questo: http://stackoverflow.com/questions/3054526/delphi-compiler-directive-to-evaluate-arguments-in-reverse –

+0

@David, Ero a conoscenza di questa 'caratteristica' C e ho imparato su SO che Java e C# valutano da sinistra a destra, ma non riuscivo a ricordare dove Delphi ha documentato (e come abbiamo appreso, la documentazione è sbagliata). – gabr

risposta

12

L'ordine di valutazione dei parametri in Delphi non è definito.

Come un interessante dimostrazione di ciò, il seguente programma ha output diverso a seconda che si target codice a 32 o 64 bit:

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

In Win64, l'ordine di valutazione è definito dall'unica convenzione di chiamata, AFAIK. In Win32 esistono diverse convenzioni di chiamata e non specificano l'ordine di valutazione, ma solo l'ordine di passaggio. –

+4

@RudyVelthuis Per quanto ne so, le convenzioni di chiamata specificano l'ordine di * passaggio * ma non specificano l'ordine di * valutazione *. Quindi discuto quel commento. –

+0

IMO, le convenzioni di chiamata possono specificare tutto ciò che desiderano, funzioni di chiamata WRT. Se viene specificato anche l'ordine di valutazione, per qualsiasi motivo lo sviluppatore della piattaforma possa avere, è meglio seguire le specifiche. Ma sono d'accordo che, AFAIK, fino ad ora, nessuna convenzione di chiamata ha fatto questo. –

5

Modificato: sembra che il compilatore può violare il comportamento descritto nella guida:

Da Calling Conventions argomento della guida (sottolineatura mia):

registro e Pascal convenzioni passano parametri da da sinistra a destra; vale a dire, il parametro più a sinistra è valutato e superato per primo e il parametro più a destra viene valutato e passato per ultimo.

+0

Si scopre che la documentazione a cui si collega non è corretta. –

+0

rende triste che il comportamento del compilatore non corrisponda all'unica fonte di documentazione ufficiale – MBo

+0

Accetto. Personalmente ritengo che sia giusto che l'ordine di valutazione non sia definito, ma la documentazione non dovrebbe indicare diversamente. –

Problemi correlati