0

in this code I think I have to write set /a counter=%counter%+1 but I just tried write it without %% and interestingly it works I don't how?! can anyone explain it

@echo off
setlocal enabledelayedexpansion
goto :main
:main
setlocal

    set /a counter=0
    set /a limit=10
    :loop
        if %counter% lss %limit% (
            echo %counter%
            set /a counter=counter+1
            goto :loop
        )
endlocal
goto :eof
3
  • 1
    In short, because the programmers programmed it to work that way. Maybe they had their reasons despite breaking the "usual rules" of batch. Maybe it was a bad programming, sold as a "feature" afterwards. Who knows? You can find arguments for both ways, but when it comes to the exact "why", you'd need to ask the programmers. (Btw, there is also the set /a counter+=1 syntax to increase the variable by one) Commented May 2 at 13:55
  • 3
    Why didn't you read the help file first? Any non-numeric strings in the expression are treated as environment variable names whose values are converted to numbers before using them. If an environment variable name is specified but is not defined in the current environment, then a value of zero is used. This allows you to do arithmetic with environment variable values without having to type all those % signs to get their values. Commented May 2 at 16:51
  • (To be fair, the help describes THAT it works that way, not WHY. (On the other hand, the "why" is off topic here)) Commented May 2 at 18:12

1 Answer 1

4

It's special to the set command with /a option.

It's the only command that has it's own variable expansion phase.
The expansion of %variable% occurs before a command or block is executed.
The expansion of !variable! occurs when a single command is to be executed.

And when the set command is executed with /a, it tries to expand variable names, here a name consists of everything except valid mathematical operators and it must not begin with a digit.

set my=8
set var=1
set my_var=66666
set my-var=66666
set arr[4]=500
set idx=4

set /a result1=my_var
set /a result2=my-var
set /a result3=arr[%idx%]

set "result"

Output:

result1=66666
result2=7
result3=500

The evaluation of such variables to numbers have some rules, like it takes only the first number (in one of the three valid number formats 0=octal 0x for hexadecimal or for decimals).
Any non valid character stops the parsing of the number, but a leading number is still valid, if there is no valid number found, take 0.

set var_a=20
set var_b=0x20
set var_c=020

set var_d=20-5
set var_e=0xffXYZ

set /a result1=var_a
set /a result2=var_b
set /a result3=var_c
set /a result4=var_d
set /a result5=var_e

set "result"

Output:

result1=20
result2=32
result3=16
result4=20
result5=255

But even if a binary format (0b) is described in the set /? help, it does not seem to work.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank u very much I understand. Is there any good source or book that I can fully learn batch ?
@Mikel91 IMHO Learning such an old language without future seems to be a waste of time. But if you still try to understand batch, I would recommend of reading some of the high ranked questions on stackoverflow or for the parser How does the Windows Command Interpreter (CMD.EXE) parse scripts?
@jeb The help output on running set /? on Windows 11 24H2 OS Build 26100.3775 (ver outputs Microsoft Windows [Version 10.0.26100.3775]) does not have anymore any information about the possibility using a binary value format. cmd.exe uses wcstol for the conversion from string to long with value 0 for function parameter base (automatic base). There is supported only automatic recognition of decimal (base 10), octal (base 8) and hexadecimal (base 16) value formats like std::strtol.
@jeb German help output on running set /? on German Windows XP SP3 (ver outputs Microsoft Windows XP [Version 5.1.2600]) describes that 0b can be used as prefix for a binary (base 2) interpreted value although that is not true because of set /A Value=0b00000011 results in the error message Invalid number. Numeric constants are either decimal (17), hexadecimal (0x11), or octal (021). on Windows XP like on Windows 11 24H2. The help output on running set /? on English Windows 7 SP1 (ver outputs Microsoft Windows [Version 6.1.7601]) contains no information about 0b too.
@Mofi The 0b binary description is still in the German help text of Microsoft Windows [Version 10.0.19045.5737]
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.