bbman225
bbman225

Reputation: 21

Batch Invalid Number error?

This is the strangest error I've ever encountered. While I've seen the:

Invalid number.  Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).

error a million times, I can't understand what's wrong with this code:

if "%ss%" == "00" (
    set /a 3n%1+=%3
    set /a 3n%1+=%4
)

This gives:

C:\Users\...>if "00" == "00" (
set /a 3n2+=1
 set /a 3n2+=3
)
Invalid number.  Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).

I can't figure out why this is happening.

Note: Even when the expression is false, the error still fires.

Upvotes: 2

Views: 470

Answers (2)

MC ND
MC ND

Reputation: 70943

I agree with SomethingDark's answer: the starting digit is causing the "wrong" behaviour and it can (must!) be solved changing the name of the variable.

The general batch parser identifies the set command, call the internal function asociated who sees the /A switch and delegates all the work to a different parser that handles the arithmetic syntax.

The source of the behaviour is the syntax allowed by the set /a arithmetic parser. While it seems obvious that set /a 3n2+=1 is adding one to a variable, the set /? help states that

  • The syntax for arithmetic set operations is set /a expression
  • The = is an operator

That is, while set /a can, and usually is used to, set the value of a variable, it allows things as set /a 1+1, without any variable involved. The variables are just one operand used by an assignation operator.

When the arithmetic parser starts its work, one of the first operations (after quote removal, initial space trim, ...) is to check if the next character to process in the input line is a digit, and if it is, the parser assumes that a numeric operand has been found and a conversion from the input command text to a number is needed to operate, and here the error is generated as 3n2 can not be converted to a number.

Of course, if the text can be converted to a number and no conversion error raises,

set /a 123=1

we will also find and error, a missing operator. The data at the left part of the equal sign has been identified as a number, and a number can not be placed as the left side of an assignation operator (a variable is needed), the parser expects a different operator that can not be found.

A similar (more obvious) case is

set /a =123+1

where we will get a missing operand error: the equal sign is a binary operator, and the left side operand can not be found.

Upvotes: 2

SomethingDark
SomethingDark

Reputation: 14325

The error comes from the fact that your variable name 3n2 starts with a number.

While the variable name is technically valid, starting it with a number is a really bad idea and you should never do it.

To avoid the error, change the first character of the variable name to a letter or an underscore.

if "%ss%" == "00" (
set /a _3n%1+=%3
set /a _3n%1+=%4
)

Upvotes: 3

Related Questions