View Issue Details

ID Project Category View Status Date Submitted Last Update 0037911 FPC Documentation public 2020-10-11 23:48 2020-10-14 16:41 Pedro Gimeno Michael Van Canneyt normal minor have not tried assigned open 0037911: Expand the FOR documentation to cover some essential aspects I went to the documentation to check if FOR loops evaluate the second argument every iteration or not, but this aspect is not mentioned. The closest thing that it says is that "Free Pascal always calculates the upper bound before initializing the counter variable with the initial value", but that alone doesn't leave it clear that this upper bound is cached and not re-evaluated during iteration (which I've checked to be the case). Furthermore, jumping from outside the loop to inside the loop via a GOTO statement is not explicitly forbidden. Doing this skips the caching phase of the upper bound, with unpredictable results, therefore it should not be allowed. Adding a check in the compiler may be difficult, but documenting that it's plainly not supported and the result is undefined is simpler. No tags attached. Attached Files

Activities

 2020-10-14 16:41 reporter   ~0126297 Please find attached a suggested patch. patch-37911.diff (2,268 bytes)    Index: ref.tex =================================================================== --- ref.tex (revision 1758) +++ ref.tex (working copy) @@ -9513,23 +9513,28 @@ \end{enumerate} After this check, the statement after \var{Do} is executed. After the execution of the statement, the control variable is increased or decreased -with 1, depending on whether \var{To} or \var{Downto} is used. +by 1, depending on whether \var{To} or \var{Downto} is used. The control variable must be an ordinal type, no other types can be used as counters in a loop. \begin{remark} \begin{itemize} -\item \fpc always calculates the upper bound before initializing -the counter variable with the initial value. +\item \fpc always evalulates the upper bound before initializing +the counter variable with the initial value, and does not evalulate it again +during iteration. \item It is not allowed to change (i.\,e. assign a value to) the value of a loop variable inside the loop. \item The value of the loop variable is undefined after a loop has -completed or if a loop is not executed at all. If the loop was terminated prematurely with an exception or a -\var{break} statement, the loop variable retains the value it had when the -loop was exited. +completed or if a loop is not executed at all. If the loop was terminated +prematurely with an exception, a \var{break} statement or a \var{goto} +statement, the loop variable retains the value it had when the loop was +exited. \item For nested procedures, a loop variable must be a local variable. -If you declare a loop variable outside the nested procedure where the loop is, the compiler will -complain. It is however allowed to use a global variable in a procedure. +If you declare a loop variable outside the nested procedure where the loop +is, the compiler will complain. It is however allowed to use a global +variable in a procedure. +\item Using \var{goto} to jump inside the body of the loop will produce +undefined results. \end{itemize} \end{remark} @@ -9574,7 +9579,8 @@ begin end. \end{verbatim} -because the variable \var{I} is not defined in \var{Nested}. +because the variable \var{i} is not defined in \var{Nested}, and it's not +global either. But the following will compile: \begin{verbatim}  patch-37911.diff (2,268 bytes)