Jump to content
Kryvich

Using Continue in repeat statement

Recommended Posts

I encountered a strange behavior when using the Continue procedure in a repeat statement. The simplified snippet:

program RepContinue;
{$APPTYPE CONSOLE}
{$R *.res}
var
  i: Integer;
begin
  i := 5;
  repeat
    Writeln(i);
    Dec(i);
    if i > 0 then
      Continue;
  until True;
  Readln;
end.

It was expected that this program will print 5 numbers: "5 4 3 2 1". But in fact, it stops immediately after “5”.

Is it a compiler error, or is it the way it should be?

Share this post


Link to post

Continue is supposed to jump to the end of the current loop (re-evaluating the condition) and not to the beginning. Thus the until statement is evaluated which in this case ends the loop. So, yes, it is the way it should be.

 

Quote

Use the continue statement within loops to pass control to the end of the innermost enclosing end brace belonging to a looping construct, such as for or while; at which point the loop continuation condition is re-evaluated.

 

 

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Posted (edited)

@Uwe Raabe Thank you.

Although in my shining new Delphi 10.3.2 the wording is a little different: 

Quote

Allows the flow of control to proceed to the next iteration of for, while, or repeat statements. 

In Delphi code, the Continue procedure causes the flow of control to proceed to the next iteration of the enclosing for, while, or repeat statement. 

Moreover, in the IDE a little green arrow behind Continue suggests that the control flow will go to the beginning of the cycle.

Repeat-Until-Loop-Screenshot.jpg.98003e26c755a09629fa3581ad04a88a.jpg

Edited by Kryvich

Share this post


Link to post

I would expect it to go to the until statement and evaluate the condition rather than blindly jump to the top. Since both for and while loops have their condition test at the top, and repeat isn't used that often, the green up-arrow is meant to point to the condition, not the top of the loop.

 

While the verbiage of the explanation may seem a bit ambiguous, the "iteration" is always gated by the condition.

 

"until true" and "while true" are not the same, and they can be deceiving to a casual reader! Indeed, I think it fooled you as well.

 

Personally, I'd use this because it's more obvious:

while true do
begin
  . . .
end;

 

Share this post


Link to post
2 hours ago, Kryvich said:

Although in my shining new Delphi 10.3.2 the wording is a little different: 

That's interesting! I quoted right from the Rio DokWiki, but perhaps the offline help is a bit different. Although, my German offline help is a translation pretty close to the English DokWiki one. Nevertheless there are other places in the docs that support the wording you quoted, so I guess it is probably completely unclear which behavior is actually intended. So the least we can expect from reporting that issue is a documentation consistent with the compiler - however that turns out then.

Share this post


Link to post
7 hours ago, Kryvich said:

It was expected that this program will print 5 numbers: "5 4 3 2 1". But in fact, it stops immediately after “5”.

Is it a compiler error, or is it the way it should be?

As others have stated, it is working as designed.  You need to change your 'until True' condition to 'until False' instead so the loop can run more than once.

 

Personally, I would just re-write the condition to not use 'Continue' at all:

program RepContinue;

{$APPTYPE CONSOLE}
{$R *.res}

var
  i: Integer;
begin
  i := 5;
  repeat
    Writeln(i);
    Dec(i);
  until i <= 0;
  Readln;
end.

 

Share this post


Link to post
Posted (edited)

@Remy Lebeau

It was a simplified snippet to highlight the problem. In my code I tried to use a repeat-until statement instead of a label and a goto statement. This statement is intended to direct an execution back to the top of code block in a special case. Now I add a control variable to bypass the check. 

  
  repeat
    var DoRepeat := False;
    ...
    if ... then begin
      ...
      if ... then begin
        DoRepeat := True;
        Continue;
      end;
      ...
    end;
    ...
  until not DoRepeat;
Edited by Kryvich
  • Like 1

Share this post


Link to post

repeat-until is slightly hard to realize construction because of its negative condition check. I use the following mnemonic: repeat stuff until condition is true.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×