views:

377

answers:

4

Hi everybody.

I'm defecting from C# to Delphi 2009, I'm liking it so far very much.

I wrote a binary search procedure, which works fine. I added a simple if-else statement at the end of my proc and it just doesn't fire! I can't see anything wrong with it and am embarrassed to have to say I am stuck. Please help!

procedure BinSearch;
var
  min,max,mid, x: integer;
  A : array[0..4] of integer;
  rslt : integer;

begin

  writeln('binary search');
  A[0] := 34; A[1] := 65; A[2] := 98; A[3] := 123; A[4] := 176;
  listarray(a);
  x := 62;
  min := 0;
  max := 4;

  repeat
    begin
    mid := (min + max) div 2;
    if x > A[mid] then
      min := mid + 1
    else
      max := mid - 1;
    end;
  until (A[mid] = x) or (min > max);

  writeln(mid);
  writeln(a[mid]);

  if A[mid] = x then
    rslt := mid
  else
    rslt := not mid;

  if 54 = 65 then
    rslt := mid
  else
    rslt := not mid;

end;

It's the if A[mid] = x then one that won't fire. when debugging neither true or false branches fire, the debugger just skips straight over them. Also the if 54 = 65 then which is just a test does the same.

The if inside my repeat loop works fine though.

If I copy the problem if statement into a mini test proc, and then call the proc it works, so it makes me think it's something else in the proc like a missing ; causing something strange to happen but I cannot see it. Please help!

+4  A: 

It could be that the debugger is just skipping over those statements even though they are actually running. Make sure that all of the options are turned on in the debugging options. In Delphi 7, they are under Project\Options under the Compiler tab.

Mark Wilkins
Thanks for you quick response. All is fine - it was working all along!I could not see anything to change in the debugger options, but it was indeed firing and just skipping over in the debugger. I guess because if ... else ... ; is one statement is something to do with it, however its very strange how the debugger WILL step into identical code in other places, and not on others. Main thing is it is working tho.I am not longer stumped and thats the main thing, thanks for your help and sry for my donkey question.
Yes, the Delphi optimizer in debug builds sometimes seems a little overly aggressive to me.
Mark Wilkins
+14  A: 

The Delphi compiler is pretty smart, and it will happily remove unused code. When I compile your code I get compiler hints saying "Value assigned to 'rslt' never used". Since the value is never used, the compiler just skips over those statements.

If you add a Writeln(rslt); to the end of your procedure, you will find that the debugger will now trace through your if statement.

Incredulous Monk
I've seen this behavior before, and I bet that's exactly what's happening!+1
Fabricio Araujo
A: 

The "Begin" statement just after the "Repeat" statement shouldn't be there. A "Repeat" doesn't use a begin. I would remove it just to be sure that it doesn't cause any problems.

Pmax
A: 

"rslt" is not used. Therefore Delphi optimizes it out.

Obviously, you want to return your result. So change your declaration to:

procedure BinSearch(var rslt: integer);

or better, make it a function:

function BinSearch: integer;

and at the end put in:

Result := rslt;

Do either of the above, and you'll find that those statements are no longer skipped over because rslt is now being used.

But, you'll find you will have a problem with your statement:

rslt := not mid;

because mid is an integer. I'm not sure what you want to return here, but I know you don't want the "not" operator to be applied to "mid".


Look at this code that I got from wikibooks. It might help you figure it out.

(* Returns index of requested value in an integer array that has been sorted
in ascending order -- otherwise returns -1 if requested value does not exist. *)

function BinarySearch(const DataSortedAscending: array of Integer;
 const ElementValueWanted: Integer): Integer;
var
    MinIndex, MaxIndex: Integer;
    { When optimizing remove these variables: }
    MedianIndex, MedianValue: Integer;
begin
    MinIndex := Low(DataSortedAscending);
    MaxIndex := High(DataSortedAscending);
    while MinIndex <= MaxIndex do begin
        MedianIndex := (MinIndex + MaxIndex) div 2; (* If you're going to change
         the data type here e.g. Integer to SmallInt consider the possibility of
         an overflow. All it needs to go bad is MinIndex=(High(MinIndex) div 2),
         MaxIndex = Succ(MinIndex). *)
        MedianValue := DataSortedAscending[MedianIndex];
        if ElementValueWanted < MedianValue then
            MaxIndex := Pred(MedianIndex)
        else if ElementValueWanted = MedianValue then begin
            Result := MedianIndex;
            Exit; (* Successful exit. *)
        end else
            MinIndex := Succ(MedianIndex);
    end;
    Result := -1; (* We couldn't find it. *)
end;
lkessler