Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Ok, explain this please...

Status
Not open for further replies.

Zinderin

Programmer
Oct 10, 2004
6
US
I'm totally confused. In the routine below, x intializes to 100 and then decrements to 1, and never gets to zero.

::blink:: What am I missing?

Thanks...

*******************************************************

Procedure SaveRecordsToFile(Name : String);
var
F : File of AddressRecord;
FN : String;
x : Integer;
begin

FN := AppPath + '\' + Name + '.DAT';

AssignFile(F,FN);
Rewrite(F);
For x := 0 to 99 do
If ARec[x].Name <> '' then Write(F,ARec[x]);

CloseFile(F);
end;
 
x starts with 0 and terminates with 99

For decreasing use

Code:
For x:= 100 [b]downto[/b] 0 do



Steven van Els
SAvanEls@cq-link.sr
 
A very interesting observation Zinderin.

If you don't believe it, try this: start a new project, drop a TButton on the form, add an OnClick handler and declare an array as follows:
Code:
var
  a: array [ 0..3 ] of string;

procedure TForm1.Button1Click(Sender: TObject);
var
  x: integer;
begin
  for x := 0 to 3 do
    ShowMessage ( a[x] );
end;
Put a breakpoint on the line for x := 0 to 3 do and you will see that x takes successive values of 4, 3, 2 and 1 when you would expect it to take the values 0, 1, 2 and 3.

Now modify the procedure so that it looks like:
Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  x: integer;
begin
  a[0] := '0';
  a[1] := '1';
  a[2] := '2';
  a[3] := '3';
  for x := 0 to 3 do
    ShowMessage ( a[x] );
end;
x still takes the values 4, 3, 2 and 1 but the ShowMessage displays the expected values of '0', '1', '2' and '3' !!!

Now modify the ShowMessage so that looks like:
Code:
    ShowMessage ( a[x] + IntToStr ( x ) );
This time the debugger shows that x takes the expected values of 0, 1, 2 and 3.

Presumably this is some clever Borland compiler optimisation but why and does it really matter?

I use Delphi 7 Pro.

Andrew
Hampshire, UK
 
I noticed this when I first started learning Delphi and it confused the life out of me when I was debugging one of my first Delphi apps! Andrew is right - it is due to the Borland compiler's optimisation techniques.

I found the following interesting comment:
9. Why does the debugger show my For loop variable counting down, not up?

The Delphi optimizer may generate loop code that decrements an internal counter instead of your variable. This behavior is guaranteed not to alter the correctness of your program. Ignore the debugger value and consider the For loop variable "unavailable due to optimization".
Source:
Clive [infinity]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer."
Paul Ehrlich
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 

Ok, here the final deal on this.

I had to turn compiler optimization off in order to get to record 0. I realize the above says just to ingore it or turn it off ... but the fact is, until I turned off compiler optimization, it just flat refused to write out record 0. Turn it off, it writes it out just fine.

Regards, and thanks everyone.
 
Delphi has a "strange" way of starting with lists, they starts with zero . If you have worked with arrays in pascal you normally start with 1. It is a long time ago when I used file of[/b, can't recall if it starts with 0 or 1.

By the way what is ARec?

Steven van Els
SAvanEls@cq-link.sr
 
FWIW:

I have had to turn off optimization since D5 because of this anomoly.

I deal with electronic transactions, I put them in a lane file (grocery store, lane 1, lane 2, etc...) lots of "polling" is done by using the same "x" in the "subjects code" where the "first x" is kept and the "last x" is kept and then arithmetic is done on the numbers. Imagine my surprise (and the *&#$ not working) when the result was negative.

Personally I find it ABOMINABLE that Delphi developers THINK it's o.k. to switch this to a decrementing loop instead of an incrementing loop and bury it in optimization without divuldging the happenings in a white paper somewhere.

The biggest problem I see is that I would like to use optimization, but if they ever "fix" this problem, it will be in D8+ and because of all the restrictions of files etc in D8 I'll never go there.

Anyway that's my BLOG
JGS

Regards and HTH,
JGS
 
Can someone produce the simplest possible Delphi program that demonstrates this optimisation bug and post it here? We should then hit Borland over the head with it.

Andrew
Hampshire, UK
 
After trying for 20 min, I can't reproduce it, although I have the feeling that there is some ["x" (size of program) for which NOT optimization is done].

I know exactly what I was doing when it happened, but do you have any clues on how to increase the size of the executable to the point where the above hypothesis would not be an issue?

Tnx
JGS
 

Yeah, this was the first time I encountered it. And this program is large. So it may be a size issue. Maybe at some point they blow a pointer or overflow.

You can see from my procedure (in my very first post), that the procedure is not rocket science.

But I'm not too keen on sending them my source code for my entire app so they can debug thier code, besides, it D7, I'm not expecting them to do anything about it.

 
Watches and break points were very usefull in the old days of sequential programming (dos, turbo pascal). In an event driven system (windows) it can drive you crazy because the program acts like a grasshopper.

Steven van Els
SAvanEls@cq-link.sr
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top