I know this question is very old, but I wanted to clarify something: "Passing by Reference" in this context does not mean you're passing a pointer around.
You're literally just passing the name of the variable as a string, then accessing the variable from the subroutine.
It works because environment variables use dynamic scoping - variables set in the caller are available to the callee, unless it shadows them by using SetLocal and then reusing the name.
SetLocal EnableDelayedExpansion
set "parm=Hello"
call :subroutine parm
REM The below will print "Hello world".
echo "%parm%"
exit /b
:subroutine
REM Now %1 contains the value "parm"
set "%1=!%1! world"
REM Now variable "parm" contains "Hello world"
exit /b
If the subroutine uses SetLocal itself, you have to use EndLocal to avoid shadowing the original variable:
EndLocal & set "%1=!%1! %local%"
But ultimately there's nothing special about the value that was passed; it's just a variable name that you use in set
, which happens to correspond to an existing variable in the outer scope.