Why CALL prints the GOTO help message in this script?And why command after that are executed twice?

后端 未结 2 812
难免孤独
难免孤独 2021-01-02 13:22

Here\'s one interesting thread. And I tried to play with the two things discussed there.

  1. You can access labels with special symbols with double expansion.
相关标签:
2条回答
  • 2021-01-02 13:33

    I'm always surprised, that you still found things that never came to my mind to test.

    Contrary to Aacini, I don't believe that :/? acts here as a valid label.
    Else this should find such a label.

    I suppose that the CALL command is internally composed of a stack pusher function and then just use GOTO to jump to the label.

    And as you are using late expansion the /? isn't detected by the CALL command itself, but by the GOTO command.
    The goto shows only the help info and finished, but as the call has already pushed the fileposition to the stack it works like calling this filepostion and later return to the same location!

    set "help=^ /?"
    call :myLabel%%help%%
    

    This shows also the help, like a GOTO :myLabel /? would do.
    But this one don't

    set "help=/?"
    call :myLabel %%help%%
    

    I suppose, the GOTO gets only the label parsed by the CALL, the other parameters are moved to %1, %2, ...

    And this could explain why only the label can use delayed expansion two times.

    @echo off
    setlocal EnableDelayedExpansion
    set "label=myLabel"
    set "pointer=^!label^!"
    call :!pointer!
    exit /b
    
    :myLabel
    echo it works
    
    0 讨论(0)
  • 2021-01-02 13:52

    Interesting! The first code may be reduced to:

    @echo off
    
    setlocal
    set "label=/?"
    
        call :%%label%%
        echo == Test message to check if the CALL or GOTO ( or neither ) command is executed  ==
    

    and still show the same output, that is, it behaves the same way than this code:

    @echo off
    
    setlocal
    
    call :/?
    echo == Test message to check if the CALL or GOTO ( or neither ) command is executed  ==
    

    where the call :/? is both a call command and a valid label, AND considering :/? a valid label. Wow!

    Why the GOTO help is displayed? No idea!!!

    EDIT: Additional tests

    This code:

    @echo off
    
    setlocal
    set "label=/?"
    
        set i=0
        call :%%label%%  &  echo Command in same line:  i=%i%
        set /A i+=10
        echo == Test message ==     i=%i%
    

    show the GOTO help screen first, and then:

    == Test message ==     i=10
    Command in same line:  i=0
    == Test message ==     i=20
    

    but if EnableDelayedExpansion is added and %i% is changed by !i! in the call line, then it shows:

    == Test message ==     i=10
    Command in same line:  i=10
    == Test message ==     i=20
    

    as "expected"...

    EDIT #2

    The test below show that the call :%%label%% command does NOT report the ERRORLEVEL=1 standard on "label not found" error:

    @echo off
    
    setlocal
    set "label=/?"
    
        call :notFound
        echo Label not found: ERRROLEVEL = %ERRORLEVEL%
        ver > NUL
        echo Reset errorlevel: ERRROLEVEL = %ERRORLEVEL%
    
        call :%%label%%
        echo == Test message == ERRROLEVEL = %ERRORLEVEL%
    
    0 讨论(0)
提交回复
热议问题