Solved

No warning! Why?

Posted on 2004-09-17
26
248 Views
Last Modified: 2010-04-05
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?
0
Comment
Question by:__alex
  • 12
  • 5
  • 3
  • +3
26 Comments
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12082065
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
 
LVL 2

Author Comment

by:__alex
ID: 12082145
???
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
 
LVL 2

Author Comment

by:__alex
ID: 12082155
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
 
LVL 6

Expert Comment

by:Leviter
ID: 12082187
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
 
LVL 2

Author Comment

by:__alex
ID: 12082218
@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
 
LVL 2

Author Comment

by:__alex
ID: 12082236
FOR CLARIFICATION:
I LIKE AND EXPECT THIS WARNING IN BOTH CASES BUT I JUST GET IT IN THE FIRST EXAMPLE.

Sorry for yelling...
0
 
LVL 17

Expert Comment

by:geobul
ID: 12082277
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
 
LVL 6

Expert Comment

by:Leviter
ID: 12082292
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
 
LVL 17

Expert Comment

by:geobul
ID: 12082327
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
 
LVL 2

Author Comment

by:__alex
ID: 12082488
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
 
LVL 2

Author Comment

by:__alex
ID: 12082508
@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
 
LVL 5

Accepted Solution

by:
tzxie2000 earned 100 total points
ID: 12083045
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
 
LVL 17

Expert Comment

by:geobul
ID: 12083079
>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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 2

Author Comment

by:__alex
ID: 12083096
@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
 
LVL 5

Expert Comment

by:tzxie2000
ID: 12083123
thanks for your points too.
you're welcome!
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12083129
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
 
LVL 2

Author Comment

by:__alex
ID: 12083147
@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
 
LVL 2

Author Comment

by:__alex
ID: 12083165
@w_alex
A where-loop? Must be a .NET feature ;-)
0
 
LVL 17

Expert Comment

by:geobul
ID: 12083387
>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
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12083641
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
 
LVL 2

Author Comment

by:__alex
ID: 12083695
@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
 
LVL 2

Author Comment

by:__alex
ID: 12083827
BTW
Code is almost identical except for:

cmp ebx, -$01
jz TForm1.Button2.Click + $44
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12084391
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
 
LVL 2

Author Comment

by:__alex
ID: 12084791
> 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
 
LVL 17

Expert Comment

by:geobul
ID: 12085147
__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
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12088990
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

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now