No warning! Why?

I'm using D5 Pro and I wonder whether this is a compiler bug...

for i := 0 to 9 do;
if i = -1 then;
=> Warning: i might be undefined.

for i := 0 to 9 do
  if i = 42 then Break;
if i = -1 then;
=> No warning!?

Anyone?
LVL 2
__alexAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
tzxie2000Connect With a Mentor Commented:
you may enter the delphi help index and type "for statements" and you will find help about "for statements"

in it there are some word below

The for statement assigns the value of initialValue to counter, then executes statement repeatedly, incrementing or decrementing counter after each iteration. (The for...to syntax increments counter, while the for...downto syntax decrements it.) When counter returns the same value as finalValue, statement is executed once more and the for statement terminates. In other words, statement is executed once for every value in the range from initialValue to finalValue. If initialValue is equal to finalValue, statement is executed exactly once. If initialValue is greater than finalValue in a for...to statement, or less than finalValue in a for...downto statement, then statement is never executed.

NOW THE WORD IS IMPORTANT BELOW

After the for statement terminates (provided this was not forced by a break or an exit procedure), the value of counter is undefined.

I think this can help you to understand it.
Delphi just do it.
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
Just guessing, not tested...
-->for i := 0 to 9 do
  if i = 42 then Break;
if i = -1 then //this check is done after the loop, so var I is intended as if it's re-inizialized

for i := 0 to 9 do begin
  if i = 42 then Break;
if i = -1 then; //now this should return the warning
end;

F68 ;-)
0
 
__alexAuthor Commented:
???
I expect a warning if I use the loop variable after the loop wheter there's a Break statement or not.
Your second example seems to be totally legal and it's not supposed to cause a warning. You don't use i after the loop. Am I missing something?
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
__alexAuthor Commented:
Using begin and end:

for i := 0 to 9 do
begin
end;
if i = -1 then
begin
end;
=> Warning: i might be undefined.

for i := 0 to 9 do
begin
  if i = 42 then Break;
end;
if i = -1 then
begin
end;
=> No warning!?
0
 
LeviterCommented:
It could also be that the compiler optimized the code. An empty for-loop could therefor be 'removed' from the code, leaving 'i' undefined. When the loop contains some code, the for-loop cannot be 'removed', leaving an assingment of 'i'.
0
 
__alexAuthor Commented:
@Leviter
This is from a real project with nonempty loops and ifs. And again: I expect a warning in my second example but there is none!
0
 
__alexAuthor Commented:
FOR CLARIFICATION:
I LIKE AND EXPECT THIS WARNING IN BOTH CASES BUT I JUST GET IT IN THE FIRST EXAMPLE.

Sorry for yelling...
0
 
geobulCommented:
Hi,

IMHO it is the Break procedure in your second example that doesn't allow the compiler to optimize the loop and therefore 'i' variable will be defined after the loop.

Regards, Geo
0
 
LeviterCommented:
Apology excepted....  :-)

Since not all code is present here, it is difficult to give a direct reason. Is the code optimized? Is 'i' a global variable? Is 'i' initialized?

Maybe this could help you further: http://buglist.jrsoftware.org/generated/entry0129.htm
0
 
geobulCommented:
Loop variables might not be defined after a loop only if the loop could be optimized (means: 'remove the loop and replace it with something else where there won't be a loop variable'). Otherwize the loop is executed as it is, i.e. using the loop variable and at the end of such unoptimized loop, the loop variable is equal to last value + 1.

Hope it is more clear now.

Regards, Geo
0
 
__alexAuthor Commented:
More complete example:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i := 1 to 3 do
  begin
    Memo1.Lines.Add(IntToStr(i));
  end;
  Memo1.Lines.Add(IntToStr(i));   // Warning
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i: integer;
begin
  for i := 1 to 3 do
  begin
    Memo1.Lines.Add(IntToStr(i));
    if (i = -1) then Break;
  end;
  Memo1.Lines.Add(IntToStr(i));   // No warning
end;
0
 
__alexAuthor Commented:
@Geo
> where there won't be a loop variable
Variable i appears in for loop of Button1Click and Button2Click.

@Leviter
Linke seems to make sens to me...
0
 
geobulCommented:
>Variable i appears in for loop of Button1Click and Button2Click.

your source code:
--->
for i := 0 to 1 do <something>;
<---
after optimization might become:
--->
<something>;
<something>;
<---

so 'i' variable is not used at all and therefore won't be initialized and won't have a value after the loop.

Regards, Geo
0
 
__alexAuthor Commented:
@tzxie2000
Ok, these important ;-) word are missing in D5 Pro but are present in D7 Personal. Thus it's not a bug in the compiler but in the help files. Thank you very much!
0
 
tzxie2000Commented:
thanks for your points too.
you're welcome!
0
 
Wim ten BrinkSelf-employed developerCommented:
Geo is right... When Delphi optimizes a for-loop, the variable used in it might not even be used. But what also happens is that something like:
> for I := 0 to 9 do...
gets compiled as:
> for I := 9 downto 0 do...

And something like:
> for I := 10 to 12 do...
Might get compiled to
> for I := 2 downto 0 do...

All this because Delphi optmizes these kinds of loops. And often optimizes for speed, not memory.

If you happen to use the value for I in your loop code, Delphi won't do much optimization, though. Still, it might reverse the direction in which you walk through the loop.

I happen to prefer a where-loop instead of the for-loop, though. It's just slightly more reliable, but not as fast.
0
 
__alexAuthor Commented:
@Geo
That's not the problem. I know the reason for the warning (i may be held in a register that is used for something else later). I was looking for an explanatation for the missing warning (-> comment of tzxie2000). But however, thank you.
0
 
__alexAuthor Commented:
@w_alex
A where-loop? Must be a .NET feature ;-)
0
 
geobulCommented:
>I was looking for an explanatation for the missing warning (-> comment of tzxie2000).

I think I've explained that in my first comment here long before tzxie2000 - Break procedure.
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
Wow, how many posts in this topic :))

BTW my guessing was right, except for an erroneus copy/past

this my post
--> //this check is done after the loop, so var I is intended as if it's re-inizialized
was meaning about after the break (breaking the loop)

should have been pasted as
-->for i := 0 to 9 do
  if i = 42 then Break;
if i = -1 then //this check is done after the loop, so var I is intended as if it's re-inizialized

for i := 0 to 9 do begin
if i = -1 then; //now this should return the warning
  if i = 42 then Break;
end;

In fact have sense your
 -> Your second example seems to be totally legal and it's not supposed to cause a warning. You don't use i after the loop. Am I missing something?


Well, you already got your answer. Better so :)
F68 ;-)
0
 
__alexAuthor Commented:
@Geo
Oops, my fault! Next time I better read your comments more careful!

Extra points for you:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21134939.html
0
 
__alexAuthor Commented:
BTW
Code is almost identical except for:

cmp ebx, -$01
jz TForm1.Button2.Click + $44
0
 
Wim ten BrinkSelf-employed developerCommented:
While loop, I meant :)

I := 0;
while I<10 do begin
  Blah;
  Inc(I);
end;

It's quite effective and allows you to check for many other conditions too.

Delphi 9 will support "for I in SomeArray do Blah;" which will be interesting, though.

Btw. Delphi reverses the loop direction for "for I := 0 to 9" to "for I := 9 downto 0" because on machinecode-level, checking if I equals zero performs faster than comparing if I equals some value... I think it saves two or three ticks per loop.

Btw. I hate statements like Break, Continue and Exit and always try to avoid them. While they can be considered useful, real developers can create code that performs just as well without those commands. It's like people who prefer to write recursive solutions for problems because it looks easier, while in fact anything that can be solved with recursion can be performed better through other solutions. I just consider the use of break a very bad habit...

Btw. I don't think the moderators allow you to create dummy Q's to award points to other experts. If you want to reward them, split the points...
0
 
__alexAuthor Commented:
> real developers
Consider me a pragmatic developer :P
> If you want to reward them, split the points...
How to perform a point split:
  1. Become a page editor
  2. Reopen question
  3. Raise points (optional)
  4. Split points
  5. Close question
  6. Quit page editor status
0
 
geobulCommented:
__alex, thank you for the suggested points but I didn't mean that in my previous post. Please, delete that question and save points for something else.

BTW. As far as I remember right 'Points for' questions are allowed if the total amount of points doesn't exceed 500 per question. So, for instance, __alex could 'legally' post up to 4 additional to this one 'Points for' questions (100 p. each).
0
 
Wim ten BrinkSelf-employed developerCommented:
You can split points easily when you accept an answer. There's a special option for this on the bottom of your open questions. Just raise the points if you want to reward more.

And about being a pragmatic developer, well... That's your choice. Means I would not like to maintain your code. :-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.