dbenham wrote:The Cool Loop is well behaved, but I can not see any benefit to the technique, given that the call loses the FOR loop variable context. And I am pretty sure that it is not calling the function from memory - I think it is still scanning the batch file for each call.
And here is verification that it's rescanning - apparently from the end of the block down, and then from the top down again, only hitting labels inside the block if none others are found. I know some of you will find this obvious, but I did it the hard way and doublechecked

Saving the following batch file as, say, in-call.cmd, with multiple :err labels placed in various places, cmd's order of preference when resolving a 'call :err' seems to be...
Code: Select all
@setlocal enableDelayedExpansion & echo off & goto :main
:err [3]
for /f %%n in ('set/a %~1 + 3') do exit /b %%n &rem 3rd choice
:err [4]
for /f %%n in ('set/a %~1 + 4') do exit /b %%n &rem 4th choice
:main
echo(
for %%n in (100 200) do (
if 1 equ 0 (
:err [5]
for /f %%n in ('set/a %~1 + 5') do exit /b %%n &rem 5th choice
)
call :err %%n
echo [%%n] !errorlevel!
call :err %%n
echo [%%n] !errorlevel!
if 1 equ 0 (
:err [6]
for /f %%n in ('set/a %~1 + 6') do exit /b %%n &rem 6th choice
)
)
set "@err=:err"
echo(
call; & call %@err%
echo call %%@err%% = call %@err% --^> errorlevel !errorlevel!
call; & call !@err!
echo call ^^!@err^^! = call !@err! --^> errorlevel !errorlevel!
%@err% &rem never call'd
!@err!
echo(
echo *** label injection failed ^^!? *** [%0]
endlocal & goto :eof
:err [1]
for /f %%n in ('set/a %~1 + 1') do exit /b %%n &rem 1st choice
:err [2]
for /f %%n in ('set/a %~1 + 2') do exit /b %%n &rem 2nd choice
Output is...
Code: Select all
C:\tmp>in-call
[100] 101
[100] 101
[200] 201
[200] 201
call %@err% = call :err --> errorlevel 1
call !@err! = call :err --> errorlevel 1
*** label injection failed !? *** [in-call]
C:\tmp>
Points of notice:
- the output verifies the first-choice :err when all are present, the rest can be verified by commenting out the preferred choice one at a time, and looking at the last digit of the returned errorlevel;
- the consecutive calls inside the for loop block show that labels are not re-targeted during execution of a loop;
- the two iterations of the for loop show that labels are not re-targeted after each step.
Finally, and mostly unrelated, but it seems that labels cannot be "injected" in a batch via macros - as the @err attempts failed. If _that_ part worked, I might have thought of a "
bizarre scenario where some variation of it is useful". But you were right not to hold your breath

Liviu