2012-05-23 10 views
7

tengo el siguiente procedimiento:Por qué compilador se salta la asignación variable de

procedure GetDegree(const num : DWORD ; var degree : DWORD ; min ,sec : Extended); 
begin 
    degree := num div (500*60*60); 
    min := num div (500*60) - degree *60; 
    sec := num/500 - min *60 - degree *60*60; 
end; 

Después de grado variable se asigna a los saltos depurador al final del procedimiento. ¿Porqué es eso?

Respuesta

17

Es una optimización. Las variables min y sec se pasan por valor. Eso significa que las modificaciones a ellos no son vistas por la persona que llama y son privadas para este procedimiento. Por lo tanto, el compilador puede determinar que asignarles no tiene sentido. Los valores asignados a las variables nunca se pueden leer. Entonces el compilador elige ahorrar tiempo y omitir las asignaciones. espero que significaba para declarar el procedimiento de la siguiente manera:

procedure GetDegree(const num: DWORD; var degree: DWORD; var min, sec: Extended); 

Como dije en la pregunta anterior, no hay realmente mucho sentido en el uso Extended. Usted estaría mejor con uno de los tipos de coma flotante estándar, Single o Double. O incluso utilizando el genérico Real que se asigna al Double.

Además, ha declarado que min es de tipo coma flotante, pero el cálculo calcula un número entero. Mi respuesta a su pregunta anterior es bastante precisa al respecto.


Le recomendaría que cree un registro para mantener estos valores. Pasar tres variables por separado hace que las interfaces de sus funciones sean muy complicadas y rompe la encapsulación. Estos tres valores solo tienen significado cuando se consideran como un todo.

type 
    TGlobalCoordinate = record 
    Degrees: Integer; 
    Minutes: Integer; 
    Seconds: Real; 
    end; 

function LongLatToGlobalCoordinate(const LongLat: DWORD): TGlobalCoordinate; 
begin 
    Result.Degrees := LongLat div (500*60*60); 
    Result.Minutes := LongLat div (500*60) - Result.Degrees*60; 
    Result.Seconds := LongLat/500 - Result.Minutes*60 - Result.Degrees*60*60; 
end; 

function GlobalCoordinateToLongLat(const Coord: TGlobalCoordinate): DWORD; 
begin 
    Result := Round(500*(Coord.Seconds + Coord.Minutes*60 + Coord.Degrees*60*60)); 
end; 
+0

Gracias una vez más David ha sido de gran ayuda hoy. No sabía acerca de estas malditas optimizaciones ¿Puedo eliminarlas de este código? – opc0de

+6

@ opc0de No desea eliminar las optimizaciones. Desea reparar su código para que devuelva los valores 'min' y' sec' a la persona que llama. De lo contrario, ¿por qué te molestas en calcularlos en primer lugar? –

+0

Ok lo tengo ahora. Gracias otra vez error estúpido :)! – opc0de

Cuestiones relacionadas