Sign in Join
Wiki copytemporary

For: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-`for` is a [[Keyword|keyword]] used in conjunction with other keywords to create [[Loops|loops]].
1+` for` is a [[Keyword|keyword]] used in conjunction with other keywords to create [[Loops|loops]].
22
33## loop with iterator variable
44
5-`for` used along with `to`/`downto` and [[Do|do]] constructs a loop in which the value of a control variable is incremented or decremented by `1` passing every iteration.
5+`for` used along with `to`/`downto` and [[Do|`do`]] constructs a loop in which the value of a control variable is incremented or decremented by `1` passing every iteration.
66
77### behavior
8-
9-``` pascal
8+```
109for controlVariable := start to finalValue do
11-begin
12- statement;
13-end;
10+ begin
11+ statement;
12+ end;
1413```
1514
16-In this example `controlVariable` is first initialized with the value of `start` (but cmp. § “legacy” below). If and as long as `controlVariable` is not greater than `finalValue`, the [[Begin|begin]] … [[End|end]] [[Frame|frame]] with all its [[statement|statements]] is executed. By reaching `end` `controlVariable` is [[Inc|incremented]] by `1` and the comparison is made, whether another iteration, whether the statement-frame is executed again.
15+In this example `controlVariable` is first initialized with the value of `start` (but cmp. § “legacy” below). If and as long as `controlVariable` is not greater than `finalValue`, the [[Begin|`begin`]] … [[End|`end`]] [[Frame|frame]] with all its [[statement|statements]] is executed. By reaching `end` `controlVariable` is [[Inc|incremented]] by `1` and the comparison is made, whether another iteration, whether the statement-frame is executed again.
1716
1817### reverse direction
1918
20-By exchanging `to` with `downto`, the variable – in the example `controlVariable` – is [[Dec|decremented]] by `1` and the condition becomes “as long as the control variable is not less than the final value.”
19+By exchanging `to` with `downto`, the variable – in the example `controlVariable` – is [[Dec|decremented]] by `1` and the condition becomes “as long as the control variable is not less than the final value.”
2120
2221### constraints
2322
2423#### scope requirements
2524
26-The control variable has to be [[Local variables|local]] inside nested [[Routine|routines]]. A routine is nested, if [[Procedural variable|routine variables]] tagged with the modifier `is nested` can store its address. Nevertheless, a [[Global variables|global variable]] is always allowed as a control variable.
25+The control variable has to be [[Local variables|local]] inside nested [[Routine|routines]]. A routine is nested, if [routine variables](</index.php?title=Procedural_variable&action=edit&redlink=1> "Procedural variable \(page does not exist\)") tagged with the modifier `is nested` can store its address. Nevertheless, a [[Global variables|global variable]] is always allowed as a control variable.
2726
2827#### immutable requirement
2928
30-While inside in a loop, it is imperative not to mess with the loop variable. Plain assignments – e. g. `controlVariable := 2` – are caught by the compiler reporting “Illegal assignment to for-loop variable "controlVariable"”. However, *indirect* manipulations are not prevented:
31-
32-``` pascal
29+While inside in a loop, it is imperative not to mess with the loop variable. Plain assignments – e. g. `controlVariable := 2` – are caught by the compiler reporting “Illegal assignment to for-loop variable "controlVariable"”. However, _indirect_ manipulations are not prevented:
30+```
3331program iteratorManipulation(input, output, stderr);
34-
35-var
36- i: longint;
37-
38-procedure foo;
39-begin
40- i := 1;
41-end;
42-
43-begin
44- for i := 0 to 2 do
32+
33+ var
34+ i: longint;
35+
36+ procedure foo;
4537 begin
46- writeLn(i);
47- foo;
38+ i := 1;
4839 end;
49-end.
40+
41+ begin
42+ for i := 0 to 2 do
43+ begin
44+ writeLn(i);
45+ foo;
46+ end;
47+ end.
5048```
5149
52-The global variable `i` is modified by calling `foo`. The program runs an [[Infinite loop|infinite loop]].
50+The global variable `i` is modified by calling `foo`. The program runs an [[Infinite loop|infinite loop]].
5351
5452#### type restrictions
5553
56-The [[Data type|type]] of `controlVariable` has to be enumerable. Assuming your system operates on [[ASCII]] you can do
57-
58-``` pascal
54+The [[Data type|type]] of `controlVariable` has to be enumerable. Assuming your system operates on [[ASCII]] you can do
55+```
5956var
60- c: char;
61-begin
62- for c := 'a' to 'z' do
57+ c: char;
6358 begin
64- writeLn(c);
65- end;
66-end.
59+ for c := 'a' to 'z' do
60+ begin
61+ writeLn(c);
62+ end;
63+ end.
6764```
6865
69-or generally use any type that is enumerable.
66+or generally use any type that is enumerable.
7067
7168#### other step widths
7269
73-Other step widths than `1` or `-1` are not possible by utilizing this syntax. You have to use other loop constructs such as [[While|while]] … `do` and manually initialize, compare and change the `controlVariable`.
70+Other step widths than `1` or `-1` are not possible by utilizing this syntax. You have to use other loop constructs such as [[While|`while`]] … `do` and manually initialize, compare and change the `controlVariable`.
7471
75-The matter, whether [[FPC|FreePascal]] could provide a syntax specifying other step widths, came up several times. In general it was regarded as “syntactic sugar”, though, and in order to stay compatible Pascal’s core, or Delphi’s extensions, in order to avoid any impetuous decisions, the developers remained rather conservative and rejected any changes in that direction.
72+The matter, whether [[FPC|FreePascal]] could provide a syntax specifying other step widths, came up several times. In general it was regarded as “syntactic sugar”, though, and in order to stay compatible Pascal’s core, or Delphi’s extensions, in order to avoid any impetuous decisions, the developers remained rather conservative and rejected any changes in that direction.
7673
77-<sup>See also [FPC issue 25549](https://gitlab.com/freepascal.org/fpc/source/-/issues/25549).</sup>
74+See also [FPC issue 25549](<https://gitlab.com/freepascal.org/fpc/source/-/issues/25549>).
7875
7976### limits
8077
81-Note, as it is common in mathematics when writing sums $`\sum_{n=0}^{k}`$ or products $`\prod_{n=1}^{k}`$ the limits are *inclusive*.
82-
83-``` pascal
78+Note, as it is common in mathematics when writing sums [math]\displaystyle{ \sum_{n=0}^{k} }[/math] or products [math]\displaystyle{ \prod_{n=1}^{k} }[/math] the limits are _inclusive_.
79+```
8480for i := 5 to 5 do
85-begin
86- writeLn(i);
87-end;
81+ begin
82+ writeLn(i);
83+ end;
8884```
8985
90-This excerpt will print one line with `5`, though you might be fooled by such thoughts as “5 to 5 – the difference is zero. So the body must never be executed.” This is in fact wrong. Not the *difference* determines the number of iterations, but the cardinality of the set constructed by the expression `[start..finalValue]`. This can be an empty set, or in the case of `[5..5]` just the single-element set $`\left\{5\right\}`$.
86+This excerpt will print one line with `5`, though you might be fooled by such thoughts as “5 to 5 – the difference is zero. So the body must never be executed.” This is in fact wrong. Not the _difference_ determines the number of iterations, but the cardinality of the set constructed by the expression `[start..finalValue]`. This can be an empty set, or in the case of `[5..5]` just the single-element set [math]\displaystyle{ \left\\{5\right\\} }[/math].
9187
92-### legacy
88+### Loop Completion
9389
94-Assuming no other manipulations were made, after the loop the value of `controlVariable` will be `final`, unless the the proper condition was not met from the start, then it is *undefined* (remains unchanged).
90+Note that the value of the "for loop variable" is undefined after a loop has completed or if a loop is not executed at all. However, if the loop was terminated prematurely with an exception or a break (or even a goto statement), the loop variable retains the value it had when the loop was exited.
9591
96-In case of empty loops (where the body is never executed), even the `start` value is not loaded. Rationale: The `controlVariable` exists for usage *inside* the loop’s body. If the loop’s body is not entered, then the value might remain unused. We generally avoid unused values, i. e. any unnecessary assignment without successive reads.
92+In case of empty loops (where the body is never executed), even the `start` value is not loaded. Rationale: The `controlVariable` exists for usage _inside_ the loop’s body. If the loop’s body is not entered, then the value might remain unused. We generally avoid unused values, i. e. any unnecessary assignment without successive reads.
9793
9894### short syntax
9995
100-For *single* statements writing a surrounding `begin` … `end` frame can be skipped resulting in:
101-
102-``` pascal
96+For _single_ statements writing a surrounding `begin` … `end` frame can be skipped resulting in:
97+```
10398for controlVariable := start to final do
104- statement;
99+ statement;
105100```
106101
107-It is advised though, to make use of that only in justified cases, where the readability is improved and it is very unlikely the loop is expanded by any additional statement. Too many programmers inadvertently fell for the pitfall before and added a properly indented line forgetting it requires a surrounding `begin` … `end` then, too.
102+It is advised though, to make use of that only in justified cases, where the readability is improved and it is very unlikely the loop is expanded by any additional statement. Too many programmers inadvertently fell for the pitfall before and added a properly indented line forgetting it requires a surrounding `begin` … `end` then, too.
108103
109-Make it a habit and always accompany `for`-loops with `begin` … `end`, leaving the option to possibly eliminate those at a *later* stage, prior a complete code freeze (but *not* right in the middle of development).
104+Make it a habit and always accompany `for`-loops with `begin` … `end`, leaving the option to possibly eliminate those at a _later_ stage, prior a complete code freeze (but _not_ right in the middle of development).
110105
111106## loop with elements
112107
113-With [[for-in loop|for … in loops]] the variable that is changed every iteration represents an element out of a collection. This works on strings, [[Array|arrays]], [[Set|sets]], and any other custom collection that implements the required iterators. Looping over an empty collection simply does nothing.
114-
115-``` pascal
108+With [[for-in loop|`for` … `in` loops]] the variable that is changed every iteration represents an element out of a collection. This works on strings, [[Array|arrays]], [[Set|sets]], and any other custom collection that implements the required iterators. Looping over an empty collection simply does nothing.
109+```
116110type
117- furniture = (chair, desk, bed, wardrobe);
118- arrangement = set of furniture;
119-var
120- thing: furniture;
121-begin
122- writeLn('all available pieces of furniture:');
123- for thing in arrangement do
111+ furniture = (chair, desk, bed, wardrobe);
112+ arrangement = set of furniture;
113+ var
114+ thing: furniture;
124115 begin
125- writeLn(thing);
126- end;
127-end.
116+ writeLn('all available pieces of furniture:');
117+ for thing in arrangement do
118+ begin
119+ writeLn(thing);
120+ end;
121+ end.
128122```
129123
130-In contrast to other loops, an index variable is not provided. In the above example `ord(thing)` will return an index, but it has to be *additionally* retrieved while it inherently exists yet still inaccessible. [[for-in loop|Proposals]] were made, whether and how to extend the syntax allowing to specify an index variable that is adjusted with every iteration.
124+In contrast to other loops, an index variable is not provided. In the above example `ord(thing)` will return an index, but it has to be _additionally_ retrieved while it inherently exists yet still inaccessible. [[for-in loop|Proposals]] were made, whether and how to extend the syntax allowing to specify an index variable that is adjusted with every iteration.
131125
132126## special commands
133127
134-Inside loops (including `for`-loops) two special commands tamper with the regular loop-program-flow. [`system.continue`](https://www.freepascal.org/docs-html/rtl/system/continue.html) skips the rest of the statements in *one* iteration. Effectively in a `for`-loop the next element/index is immediately assigned to the control variable, the regular check is performed, and processing of all the statements might start from the top again. Additionally [[Break|system.break]] instantly skips the whole loop altogether. This is different to [`system.exit`](https://www.freepascal.org/docs-html/rtl/system/exit.html), which exits the whole frame, but loops do not create frames (but [[Block|blocks]] do).
128+Inside loops (including `for`-loops) two special commands tamper with the regular loop-program-flow. [`system.continue`](<https://www.freepascal.org/docs-html/rtl/system/continue.html>) skips the rest of the statements in _one_ iteration. Effectively in a `for`-loop the next element/index is immediately assigned to the control variable, the regular check is performed, and processing of all the statements might start from the top again. Additionally [[Break|`system.break`]] instantly skips the whole loop altogether. This is different to [`system.exit`](<https://www.freepascal.org/docs-html/rtl/system/exit.html>), which exits the whole frame, but loops do not create frames (but [[Block|blocks]] do).
135129
136-Their usage however is usually discredited, since they “disqualify” the loop’s iteration condition. One has to *know* a loop’s body contains such commands, in order to actually determine how often a loop is executed. Without such, you can tell how many times a loop is run just by inspecting the loop’s head or tail respectively.
130+Their usage however is usually discredited, since they “disqualify” the loop’s iteration condition. One has to _know_ a loop’s body contains such commands, in order to actually determine how often a loop is executed. Without such, you can tell how many times a loop is run just by inspecting the loop’s head or tail respectively.
137131
138132## see also
139133
140-- [[Example: Why the loop variable should be of signed type]]
141-- [[sRangechecks|{$rangechecks}]]
134+ * [[Example: Why the loop variable should be of signed type]]
135+ * [`{$rangechecks}`](</index.php?title=sRangechecks&action=edit&redlink=1> "sRangechecks \(page does not exist\)")
142136
137+
138+**Keywords:** [[Begin|begin]] — [[Do|do]] — [[Else|else]] — [[End|end]] — for — [[If|if]] — [[Repeat|repeat]] — [[Then|then]] — [[Until|until]] — [[While|while]]
139+
143140---
144-*From the Free Pascal wiki, page "For", as it stood on 2022-07-16 after a change by Kirinn, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
141+*From the Free Pascal wiki, page "For", as the Internet Archive kept it on 2025-03-19, last changed on 2024-08-15. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history