-------My---research on call echo-----------------------------------
1---the standard usage of call
Example 1:
call :a
goto:eof
:a
:echo 123
Example 2:
call :a 123
goto:eof
:a
echo %1
Combine examples 1 and 2, and write them in a nonstandard form:
Example 1------>call echo 123----echoes 123
Example 2----->call echo %1---if you save the file as nn.bat and enter nn 123 , then it echoes 123
Example 3-----call echo %%i ---echoes i---this shows that 2 % signs were stripped off, call and echo each strip off one
So call echo is actually shorthand for calling a subroutine. That makes it easy to explain why call has the function of delayed environment variables, but it does not actually
turn on delayed environment variables. It is only the result of calling a subroutine.
2-----an example of call inside for
for %%i in (0 1 2) do (
set t=%%i
echo %t%
)
Because bat is interpreted as it executes, in the end it only shows---->2
Now look at this:
call :a
goto:eof
:a
set t=123
for %%i in (0 1 2) do (
set t=%%i
echo %t%
)
It echoes---》123 123 123, because what cmd executes is an interpreted program.
Change it a bit
call:a %t%
goto:eof
:a
set t=123
for %%i in (0 1 2) do (
set t=%%i
echo %1
)
At this time call invokes the subroutine parameter, and it echoes----》2 2 2
The previous line used call to invoke the result from before the for executed, this line invokes the result after the for executed
From this, the conclusion is: if you want to invoke the result after the for executes, you should invoke the subroutine parameter.
Change the previous line a bit more
@echo off
set t=123
for %%i in (0 1 2) do (
set t=%%i
call:a
:a
echo %t%
)
At this time it shows----》0 123 1 123 2 123. This line shows that call can make the data pointer move together with the for statement while the for is executing, but after the for finishes, it returns to
its initial state. This function of call is equivalent to the function of delayed environment variables.
There is no way for this line to avoid pushing t=123 into the stack; no matter where you add goto:eof it won't work. This is because the pivot point call pushes the preceding data into the stack. Here call considers the preceding data to be t=123 , and after call it automatically pops the original data back out of the stack, so then we see this dance of data: 0 123 1 123 2 123. Unfortunately bat has no statement for controlling the stack. After countless people researched it, a pathological way of writing was found to solve this problem.
Change it again:
@echo off
set t=123
for %%i in (0 1 2) do (
set t=%%i
call echo %%t%%
)
At this time it echoes-----》0 1 2
The reason is this: the principle of call execution is that it first pushes the preceding result into the stack, then enters the branch point, and after executing the contents at the branch point, it pops the saved data back out of the stack, then returns to the next branch point after call and continues forward.
Although the statement above is pathological, that extra % sign just happens to anesthetize call. For that extra % sign, call thinks that the data it should push into the stack is the data from the start of the for, and on each loop of for , call pushes that loop's data into the stack. After call finishes executing the subroutine (that is, the echo %%t%% in this pathological form), it pops the data back out of the stack, then executes the next statement, which is to enter the next loop of for. In the call statement the data pointer %t% always points to storage unit t , and the value for each loop of for is stored in storage unit t. Thus the changing value of t can be seen dynamically. The method is pathological, but this is the only thing that can be done, since Microsoft never made a command to manage the stack. Delayed environment variables should also be using stack technology. The statement setlocal enabledelayedexpansion pushes the preceding data into the stack. endlocal pops the data that was pushed into the stack back out. %t% ,!t! are data pointers, pointing to storage unit t, so the data that call pushes into the stack is the data of for.
000This viewpoint is my own original creation. If anyone has a different opinion, discussion is welcome.
[ Last edited by 5yue5 on 2009-3-1 at 04:44 ]
1---the standard usage of call
Example 1:
call :a
goto:eof
:a
:echo 123
Example 2:
call :a 123
goto:eof
:a
echo %1
Combine examples 1 and 2, and write them in a nonstandard form:
Example 1------>call echo 123----echoes 123
Example 2----->call echo %1---if you save the file as nn.bat and enter nn 123 , then it echoes 123
Example 3-----call echo %%i ---echoes i---this shows that 2 % signs were stripped off, call and echo each strip off one
So call echo is actually shorthand for calling a subroutine. That makes it easy to explain why call has the function of delayed environment variables, but it does not actually
turn on delayed environment variables. It is only the result of calling a subroutine.
2-----an example of call inside for
for %%i in (0 1 2) do (
set t=%%i
echo %t%
)
Because bat is interpreted as it executes, in the end it only shows---->2
Now look at this:
call :a
goto:eof
:a
set t=123
for %%i in (0 1 2) do (
set t=%%i
echo %t%
)
It echoes---》123 123 123, because what cmd executes is an interpreted program.
Change it a bit
call:a %t%
goto:eof
:a
set t=123
for %%i in (0 1 2) do (
set t=%%i
echo %1
)
At this time call invokes the subroutine parameter, and it echoes----》2 2 2
The previous line used call to invoke the result from before the for executed, this line invokes the result after the for executed
From this, the conclusion is: if you want to invoke the result after the for executes, you should invoke the subroutine parameter.
Change the previous line a bit more
@echo off
set t=123
for %%i in (0 1 2) do (
set t=%%i
call:a
:a
echo %t%
)
At this time it shows----》0 123 1 123 2 123. This line shows that call can make the data pointer move together with the for statement while the for is executing, but after the for finishes, it returns to
its initial state. This function of call is equivalent to the function of delayed environment variables.
There is no way for this line to avoid pushing t=123 into the stack; no matter where you add goto:eof it won't work. This is because the pivot point call pushes the preceding data into the stack. Here call considers the preceding data to be t=123 , and after call it automatically pops the original data back out of the stack, so then we see this dance of data: 0 123 1 123 2 123. Unfortunately bat has no statement for controlling the stack. After countless people researched it, a pathological way of writing was found to solve this problem.
Change it again:
@echo off
set t=123
for %%i in (0 1 2) do (
set t=%%i
call echo %%t%%
)
At this time it echoes-----》0 1 2
The reason is this: the principle of call execution is that it first pushes the preceding result into the stack, then enters the branch point, and after executing the contents at the branch point, it pops the saved data back out of the stack, then returns to the next branch point after call and continues forward.
Although the statement above is pathological, that extra % sign just happens to anesthetize call. For that extra % sign, call thinks that the data it should push into the stack is the data from the start of the for, and on each loop of for , call pushes that loop's data into the stack. After call finishes executing the subroutine (that is, the echo %%t%% in this pathological form), it pops the data back out of the stack, then executes the next statement, which is to enter the next loop of for. In the call statement the data pointer %t% always points to storage unit t , and the value for each loop of for is stored in storage unit t. Thus the changing value of t can be seen dynamically. The method is pathological, but this is the only thing that can be done, since Microsoft never made a command to manage the stack. Delayed environment variables should also be using stack technology. The statement setlocal enabledelayedexpansion pushes the preceding data into the stack. endlocal pops the data that was pushed into the stack back out. %t% ,!t! are data pointers, pointing to storage unit t, so the data that call pushes into the stack is the data of for.
000This viewpoint is my own original creation. If anyone has a different opinion, discussion is welcome.
[ Last edited by 5yue5 on 2009-3-1 at 04:44 ]


