Labels in Batch Files
Labels normally mark the beginning
of a code block that is the target of a GOTO instruction, but they can also be
used for comments. Labels begin with ':' and contain up to eight characters -
anything beyond the first eight will be ignored, both in the label and in the
GOTO command. Not all characters are permissible in labels: those that
COMMAND considers special (delimiters and markers), redirection
characters, and wildcards - specifically
Particularly weird behavior results if there are spaces between the colon and the label, and the label is a valid internal COMMAND.COM command. Try
: echo
: echo
: echo
: echo
either from a batch file or at a command prompt. In this case, the colon is not interpreted as a label marker, but as some kind of string manipulation command. Unfortunately, this works only with internal DOS commands so it is quite useless for string manipulation in general.
There are some interesting side effects of some of these characters, for example:
goto the label
goto end
:the label
echo here
:end
actually works, but
goto the label
goto end
:the wrong label
echo wrong label
goto end
:the label
echo right label
:end
works, but not
as intended - COMMAND considers "the " and "the label" as equivalent,
so only the first three characters count. However, if the space is replaced
with character 255 (usually rendered as a blank), ... well, I'll leave that to
the user's imagination, since I can't reproduce the character here, but it can
be used to obfuscate the code by having apparently identical GOTOs and labels
that are really quite different.
Note: "goto" is a valid label name and a valid environment variable name, so
the following bit of total obfuscation is valid code
set goto=goto
%goto%=%goto%
:goto
(remember that '=' is a delimiter, and works as if it were a space). However, variables cannot be used in the actual label, so
set goto=goto
%goto%=%goto%
:%goto%
is not valid code.
The special case of
::
is of use as a comment marker - the line is parsed as a label, but the parsing is aborted on the second character, so it takes COMMAND far less time to process it than does a traditional remark, which must be parsed for redirection as well as commands.
In GOTO statements, label names may well be wholly or partially variable. This can often simplify program flow control. I find it convenient, when stripping characters from a string, to toggle the label name in a goto statement so that the two calls for each invocation of the FOR loop pass first through the code to handle the leading character and second through the code to deal with resetting the FOR variable to strip the next character. In outline, this could be
@echo off
%1 %2
set fork=char
:loop
if "string" == "" goto end
for %%a in (/%string%) do call %0 goto pass2 %%a
goto loop
:pass2
goto %fork%
:char
set fork=str
set %wip%=%wip%%3
goto end
:str
set fork=char
set string=%3
goto end
:end
The above is not working code - it omits the handling of the substring to which the characters are appended, and also the clearing of STRING to terminate the action when the wanted characters have been obtained. Real code that uses the principle to build YYMMDD date strings for use in file names can be found in the Examples section.
Another use for variable label names in GOTO statements is to allow simulation of a return from a function call:
@echo off
:f1
set return=1
goto function
:r1
echo The function returned to R1
:f2
set return=2
goto function
:r2
echo The function returned to R2
:f3
set return=3
goto function
:r3
echo The function returned to R3
goto end
:function
echo The function was called from F%return%
goto r%return%
:end