Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why compiler skips assigning variable

I have the following procedure :

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;

After degree variable gets assigned the debugger skips to the end of the procedure . Why is that?

like image 221
opc0de Avatar asked May 23 '12 18:05

opc0de


1 Answers

It's an optimisation. The variables min and sec are passed by value. That means that modifications to them are not seen by the caller and are private to this procedure. Hence the compiler can work out that assigning to them is pointless. The values assigned to the variables can never be read. So the compiler elects to save time and skip the assignments. I expect that you meant to declare the procedure like this:

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

As I said in your previous question, there's not really much point in using Extended. You would be better off with one of the standard floating point types, Single or Double. Or even using the generic Real which maps to Double.

Also, you have declared min to be of floating point type, but the calculation computes an integer. My answer to your previous question is quite precise in this regard.


I would recommend that you create a record to hold these values. Passing three separate variables around makes your function interfaces very messy and breaks encapsulation. These three values only have meaning when consider as a whole.

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;
like image 55
David Heffernan Avatar answered Sep 30 '22 00:09

David Heffernan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!