var expansion behavior when var name contain equal signs

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
neorobin
Posts: 47
Joined: 01 May 2012 12:18

var expansion behavior when var name contain equal signs

#1 Post by neorobin » 19 Oct 2014 06:15

The following code did some tests:
When the tail of the variable name followed by several equal signs

For example:
$=====
_========

Can use the set command to assign such a variable success?

If successful assignment, you can use what form do variable expansion?

When tested under WIN XP 32bit, the assignment fails;

But when under WIN7 64bit, some forms success, but others fails.

The rule is unknown.

When the variable name with an underscore _ as the first character, when the count of the tail equal signs equals to 1, 2, 5, 6, 10, 11, 14, 17, 20, and more than 20, can be successfully expanded.

And when the first character of the variable name is $, when the count of the tail equal signs reached or more than 20, it can successfully expand.
When the first character is replaced by: @ # ; also get this result.

testing code:

Code: Select all

@echo off & mode 160, 1000

set _====================================================================================================VAL
set $====================================================================================================VAL
set #====================================================================================================VAL
set @====================================================================================================VAL
set ;====================================================================================================VAL

REM will report: The syntax of the command is incorrect.
set =====================================================================================================VAL

set _
set $

pause


echo _ is [%_%]
echo _= is [%_=%]
echo _== is [%_==%]
echo _=== is [%_===%]
echo _==== is [%_====%]
echo _===== is [%_=====%]
echo _====== is [%_======%]
echo _======= is [%_=======%]
echo _======== is [%_========%]
echo _========= is [%_=========%]
echo _========== is [%_==========%]
echo _=========== is [%_===========%]
echo _============ is [%_============%]
echo _============= is [%_=============%]
echo _============== is [%_==============%]
echo _=============== is [%_===============%]
echo _================ is [%_================%]
echo _================= is [%_=================%]
echo _================== is [%_==================%]
echo _=================== is [%_===================%]
echo _==================== is [%_====================%]
echo _===================== is [%_=====================%]
echo _====================== is [%_======================%]
echo _======================= is [%_=======================%]
echo _======================== is [%_========================%]
echo _========================= is [%_=========================%]
echo _========================== is [%_==========================%]
echo _=========================== is [%_===========================%]
echo _============================ is [%_============================%]
echo _============================= is [%_=============================%]
echo _============================== is [%_==============================%]
echo _=============================== is [%_===============================%]
echo _================================ is [%_================================%]
echo _================================= is [%_=================================%]
echo _================================== is [%_==================================%]
echo _=================================== is [%_===================================%]
echo _==================================== is [%_====================================%]
echo _===================================== is [%_=====================================%]

pause

echo $ is [%$%]
echo $= is [%$=%]
echo $== is [%$==%]
echo $=== is [%$===%]
echo $==== is [%$====%]
echo $===== is [%$=====%]
echo $====== is [%$======%]
echo $======= is [%$=======%]
echo $======== is [%$========%]
echo $========= is [%$=========%]
echo $========== is [%$==========%]
echo $=========== is [%$===========%]
echo $============ is [%$============%]
echo $============= is [%$=============%]
echo $============== is [%$==============%]
echo $=============== is [%$===============%]
echo $================ is [%$================%]
echo $================= is [%$=================%]
echo $================== is [%$==================%]
echo $=================== is [%$===================%]
echo $==================== is [%$====================%]
echo $===================== is [%$=====================%]
echo $====================== is [%$======================%]
echo $======================= is [%$=======================%]
echo $======================== is [%$========================%]
echo $========================= is [%$=========================%]
echo $========================== is [%$==========================%]
echo $=========================== is [%$===========================%]
echo $============================ is [%$============================%]
echo $============================= is [%$=============================%]
echo $============================== is [%$==============================%]
echo $=============================== is [%$===============================%]
echo $================================ is [%$================================%]
echo $================================= is [%$=================================%]
echo $================================== is [%$==================================%]
echo $=================================== is [%$===================================%]
echo $==================================== is [%$====================================%]
echo $===================================== is [%$=====================================%]

pause
Last edited by neorobin on 19 Oct 2014 10:32, edited 1 time in total.

Squashman
Expert
Posts: 4465
Joined: 23 Dec 2011 13:59

Re: the problem about set command and variable expansion whi

#2 Post by Squashman » 19 Oct 2014 06:40

I am not sure why on Earth you would want to name your environmental vvariables that way. For starters, the larger the variable name the slower your code will execute.

neorobin
Posts: 47
Joined: 01 May 2012 12:18

Re: the problem about set command and variable expansion whi

#3 Post by neorobin » 19 Oct 2014 06:57

Yes
I did not name so long and strange variables.

I'm just curious how to process variable expansion when variable name include equal signs :?: :D

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: the problem about set command and variable expansion whi

#4 Post by Aacini » 19 Oct 2014 09:32

The variable name may never include an equal sign. The name of the variable ends at the first equal sign; the rest of equal signs are assigned to the variable value.

Antonio

neorobin
Posts: 47
Joined: 01 May 2012 12:18

Re: the problem about set command and variable expansion whi

#5 Post by neorobin » 19 Oct 2014 10:06

Aacini wrote:The variable name may never include an equal sign. The name of the variable ends at the first equal sign; the rest of equal signs are assigned to the variable value.

Antonio


Maybe "never include an equal sign" is the truth.

Or you can use the equal signs as part of the variable name.

Under Win7 64bit

Code: Select all

set _==5
echo %_=%
set /a %_=% + 3

Output

Code: Select all

5
8


But! the variable expansion can change the memory scene?

Code: Select all

set _==5
echo %_%
echo %_=%
set /a %_=% + 3
Output

Code: Select all

=5
%_=%
Missing operand.


And,

Code: Select all

set _==5
echo %_=%
echo %_%
set /a %_=% + 3

Output

Code: Select all

5
%_%
8

jeb
Expert
Posts: 1041
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: var expansion behavior when var name contain equal signs

#6 Post by jeb » 19 Oct 2014 13:38

Hi neorobin,

I'm impressed to see a really unexpected new behaviour :D

I know some strange behaviour with variable names containing equal signs before, but I only examined some sorts of multiple equal signs.
Like

Code: Select all

set var=one=two=three
echo %var=one=two%
echo %var=one%
echo %var%

Output wrote:three
two=three
one=two=three


But your example shows that you can change the behaviour with a variable read access.

My first test shows that it works with one character in front of the equal sign,
but not with two or more characters (I made a complete proof by testing with up to 4 characters).

Code: Select all

@echo off
setlocal
echo Test1
set X==5
echo #X= '%X=%'
if "%X%" == "" (
   echo # EFFEKT #
) ELSE (
   echo Normal %X%
)

Output wrote:Test1
#X= '5'
# EFFEKT #

Code: Select all

@echo off
setlocal
echo Test2
set XXXX==5
echo #XXXX= '%XXXX=%'
if "%XXXX%" == "" (
   echo # EFFEKT #
) ELSE (
   echo Normal %XXXX%
)

Output wrote:Test2
#XXXX= '5'
Normal =5


But another strange thing is the reset logic for the "read access effect"

Code: Select all

@echo off
setlocal
echo Test3
set X==5
echo #X= '%X=%'
echo #X  '%X%'
SET Y=1
echo #X  '%X%'

Output wrote:Test3
#X= '5'
#X ''
#X '=5'

Strange ... :?:

But nice to see something new :D

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: var expansion behavior when var name contain equal signs

#7 Post by Aacini » 19 Oct 2014 21:05

This is interesting! The last time I did a test on this point was many years ago and at that time a variable name could not include an equal sign; if you tried to do so, the variable was reported as undefined...

The current Windows API documentation is very clear:

Windows API wrote:The name of an environment variable cannot include an equal sign (=).


However, it seems that this checking was removed from modern Windows environment access functions.

About the strange behavior, I can only guess that the mechanism used to access variable values is based on a search pointer that, after reporting the value of an existing variable, it leaves such pointer after that value. If the next access request a variable that is located in the environment after the last accessed one (in alphabetical order), the search for its name is performed from the last position of the pointer on. Any change in the environment reset the search pointer to the beginning of the environment. I think this mechanism explains all previous cases.

Antonio

jeb
Expert
Posts: 1041
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: var expansion behavior when var name contain equal signs

#8 Post by jeb » 20 Oct 2014 01:23

Aacini wrote:The current Windows API documentation is very clear:
Windows API wrote:
The name of an environment variable cannot include an equal sign (=).

The documentation is sometimes very clear, but more often simply false :evil:

A variable access to one variable can influence the variable access of another variable.

Code: Select all

@echo off
setlocal
echo Test4
SET X==5
SET Y==6
echo OutX %%X=%% '%x=%'
echo OutY %%Y=%% '%y=%'
echo(
echo %%X%%  '%x%'
echo %%Y%%  '%y%'

Test4
OutX %X=% '5'
OutY %Y=% '6'

%X% ''
%Y% ''


Now I swap only the lines OutX and OutY

Code: Select all

@echo off
setlocal
echo Test4
SET X==5
SET Y==6
echo OutY %%Y=%% '%y=%'
echo OutX %%X=%% '%x=%'
echo(
echo %%X%%  '%x%'
echo %%Y%%  '%y%'

But now the output of %X=% is empty :?:
Test5
OutY %Y=% '6'
OutX %X=% ''

%X% '=5'
%Y% ''


Very strange ...

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: var expansion behavior when var name contain equal signs

#9 Post by penpen » 20 Oct 2014 07:16

So I think Aacini is right with his assumption that (search) pointers are used to speed up variable access. Because of the environment structure i additionally assume, that such pointers are created for all variables preceding the accessed variable, too (these pointers are computed anyway, so storing them sounds like a good idea).

Environment structure:
The variables/values are stored as null terminated strings within the environment (block), with an additional null at the end of the block data. These strings must be sorted alphabetically (case insensitive), see:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682009(v=vs.85).aspx

Example (null value is denoted as \0):
The envrionment block with the only variables/value pairs "X"/"=5" and "Y"/"=6" is "X==5\0Y==6\0\0" (without the doublequotes).

penpen

Post Reply