0

So, I have this, that has recursion, (which is a plagiarised version of this code). I reworked it a little bit for own understanding

@echo off
set /A fst=0
set /A fib=1
set /A limit=1000
call :myFibo fib, %fst%, %limit%
echo The next Fibonacci number greater or equal %limit% is %fib%.
exit /B 0
:myFibo
SETLOCAL
    echo begin of funct %1, %2, %3
    set /A Number1=%2
    set /A Number2=%1
    set /A Limit=%3
    set /A NumberN=Number1+Number2
    REM
    if %NumberN% LSS %Limit% call:myFibo NumberN, %Number2%, %Limit%
(
    ENDLOCAL 
    set %1=%NumberN%
)
exit /B 0

that gives following output:

begin of funct fib, 0, 1000
begin of funct NumberN, 1, 1000
begin of funct NumberN, 1, 1000
begin of funct NumberN, 2, 1000
begin of funct NumberN, 3, 1000
begin of funct NumberN, 5, 1000
begin of funct NumberN, 8, 1000
begin of funct NumberN, 13, 1000
begin of funct NumberN, 21, 1000
begin of funct NumberN, 34, 1000
begin of funct NumberN, 55, 1000
begin of funct NumberN, 89, 1000
begin of funct NumberN, 144, 1000
begin of funct NumberN, 233, 1000
begin of funct NumberN, 377, 1000
begin of funct NumberN, 610, 1000
The next Fibonacci number greater or equal 1000 is 1597.

There is a couple of things I don't understand:

  • why fib and NumberN variables are passed without %% and are treated as strings when I echo them?
  • what is the purpose of parentheses around ENDLOCAL and set?
  • As of my understanding NumberN variable should be undefined after ENDLOCAL, but it still can be used
Compo
  • 36,585
  • 5
  • 27
  • 39
  • I have modified your question to include the original location of the code you linked to. I have done that because it should show you better, how to use it properly. – Compo Sep 08 '20 at 15:24
  • @Compo Thank you for clarification, original source has a better looking code indeed. But I still cannot figure out answers to my questions. If you have answers could you please explain about parenthesis with ENDLOCAL and variables used to store return value? – Olexandr.S Sep 08 '20 at 16:23
  • 3
    `cmd.exe` parses the line containing `ENDLOCAL`, which removes any variables or values created since the previous `SETLOCAL` command. When there is a parenthesised command block, it parses the entire block, which includes a variable, _(enclosed using the now correct `%`)_, and stores it prior the `ENDLOCAL` completing. To get a better insight into how cmd.exe parses scripts, please read the excellent answers to **[this question](https://stackoverflow.com/q/4094699/)**, _(created by some of those responsible for the original code I linked)_. – Compo Sep 08 '20 at 16:59
  • It can be seen on [debugging the batch file](https://stackoverflow.com/a/42448601/3074564) that Windows command processor parses the entire command block starting with `(` and ending with matching `)` and replaces `set %1=%NumberN%` by, for example, `set NumberN=13` or `set fib=13` before executing the command `endlocal` to restore the previous execution environment and next the command `set` as displayed in console window. Read [this answer](https://stackoverflow.com/a/38676582/3074564) for details about the commands __SETLOCAL__ and __ENDLOCAL__. – Mofi Sep 08 '20 at 17:12
  • It would be also possible to use `ENDLOCAL & set %1=%NumberN%` as described by my answer on [single line with multiple commands using Windows batch file](https://stackoverflow.com/a/25344009/3074564). Further I recommend not using `set /A` (arithmetic expression) just for the definition of an environment variable with a number, see [Why is no string output with 'echo %var%' after using 'set var = text' on command line?](https://stackoverflow.com/a/26388460/3074564) The usage of an arithmetic expression like `set /A fib=1` instead of `set fib=1` or `set "fib=1"` is just wasting CPU cycles. – Mofi Sep 08 '20 at 17:16
  • thank you @mofi, all your links were pretty useful. considering [this code](https://www.dostips.com/?t=FunctionTutorial.RecursiveFunctions) and what I've read so far I cannot understand what's the difference between (ENDLOCAL IF "%~1" NEQ "" SET "%~1=%NumberN%" ) and IF "%~1" NEQ "" SET "%~1=%NumberN%" ENDLOCAL While debugging, I see that it executes differently, but I don't get why, Could you please clarify this? – Olexandr.S Sep 09 '20 at 16:05
  • Have you carefully read also my answer on [Echoing a URL in Batch](https://stackoverflow.com/a/31360955/3074564)? No, I recommend to do that and read also [Variables are not behaving as expected](https://stackoverflow.com/questions/30282784/). The first code in your comment above results in reading the entire command block from batch file, replacing both `%~1` by first argument of called subroutine, replacing `%NumberN%` by current value of environment variable `NumberN` as defined after `SETLOCAL`, running `ENDLOCAL` to discard current environment variables list and restore previous list, ... – Mofi Sep 10 '20 at 16:57
  • ... and then running command `set` with variable name and string to assign already before running `ENDLOCAL` to define the environment variable with name passed to the subroutine with the string value determined between `SETLOCAL` and `ENDLOCAL` in the environment defined before __execution__ of `SETLOCAL` and restored after __execution__ `ENDLOCAL`. The second code runs the string comparison using `NEQ` designed primary for integer comparisons instead of the string comparison `IF NOT "%~1" == ""` which on result true results in execution of command `SET` to define in current environment ... – Mofi Sep 10 '20 at 17:02
  • ... the variable with name passed as first argument to the subroutine and the string value currently assigned to environment variable `NumberN`. Next is executed `ENDLOCAL` which results in discarding all environment variables defined or modified between __execution__ of `SETLOCAL` and `ENDLOCAL` and restoring the environment variables list as defined on calling the subroutine. So `SET "%~1=%NumberN%"` is completely useless in second case as the variable defined by this command line with the assigned string is discarded next on execution of `ENDLOCAL` without being ever used. – Mofi Sep 10 '20 at 17:07

0 Answers0