Forum > General
Bug in loops in x32 mode
LemonParty:
Hello.
I have next function:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TestFunc(constref Buf: ShortInt; Range: SizeUInt): SizeUInt;const cInByte = High(Byte) - 15;{number of elements in 1 chunk}var eBuf: array [1..High(Word)] of ShortInt absolute Buf; i: SizeInt;begin Result:= Low(eBuf); for i:= 0 to Pred(Range div cInByte) do begin end; WriteLn('i ',i); Readln;end;I call it like this
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TestFunc(PShortInt(nil)^, 64)The output is
--- Quote ---i 4200096
--- End quote ---
If compile this in x64 mode i is as expected 0.
Windows, FPC 3.2.2
TRon:
--- Quote from: LemonParty on May 10, 2024, 04:21:06 pm ---If compile this in x64 mode i is as expected 0.
--- End quote ---
That 0 is a nonsense result.
See documentation.
--- Quote ---Remark
* Free Pascal always calculates the upper bound exactly once before initializing the counter variable with the initial value.
* It is not allowed to change (i. e. assign a value to) the value of a loop variable inside the loop.
* The value of the 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 goto statement, the loop variable retains the value it had when the loop was exited.
* 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.
* The compiler does not expliticly forbid jumping with a goto statement into a for loop block, but doing so will result in unpredictable behaviour.
--- End quote ---
Thaddy:
The value of the loop variable once the loop has finished also differs between FPC and Delphi and even between different Delphi versions. Mind you this is the perfect example of "undefined" or "implementation detail". Delphi also documents it as undefined:
https://docwiki.embarcadero.com/RADStudio/Alexandria/en/W1037_FOR-Loop_variable_%27%25s%27_may_be_undefined_after_loop_%28Delphi%29
The solution mentioned in that documentation works also for FreePascal: use either exit or a goto (or keep track).
This is asked for years and I get a bit fed up by answering that over and over again.
So plz don't ask again....Better never discuss it again. The world will be a better place.
It is certainly NOT a bug!
Thaddy:
I forgot about one (1) single recent feature in both Delphi and FPC: Variables can be declared volatile and in that case the loop variable obeys and in all optimization levels and in both compilers:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---// FreePascal syntax and delphi syntax differs slightly.program Project6;{$ifdef fpc}{$mode delphi}{$endif}{$apptype console}var{$ifndef fpc} [volatile]{$endif} i:integer = 0;begin{$ifdef fpc} i := volatile(i);{$endif} while i < 10 do begin writeln(i); inc(i); end; writeln('This is outside of the loop: ',i); //expect 10 readln;end.Making the loop counter volatile makes that the compiler won't touch it, so the answer for the last one is always 10. Tested Delphi 32 11 CE, FreePascal 3.3.1 Windows64 and Linux64.
So, there is a way, now maybe PascalDragon will explain why that is the case or am I wrong again?
(In this case I don't think so!)
You will need FPC trunk and Delphi 10.3 or higher to test this.
ASerge:
--- Quote from: Thaddy on May 10, 2024, 05:46:24 pm ---Making i volatile makes that the compiler won't touch it, so the answer for the last one is always 10. Tested Delphi 32 11 CE, FreePascal 3.3.1 Windows64 and Linux64.
--- End quote ---
For the while loop, such difficulties are not necessary, in this case, the loop variable always has a certain value.
But this is a hint for the author of the topic - use while, not for in this case.
Navigation
[0] Message Index
[#] Next page