0

the following should print false and then true but instead it prints false and false I debugged it a bit, and it seems like when the batch is in the if, the call woeks, but does not set res

why is that?

@echo off
set res=true
Call :IsSame None None1

if false==false (
    echo %res%
    Call :IsSame None2 None2
    echo %res%
)

GOTO :EOF
:IsSame 
echo isSame
set res=false
if %~2==All (
    set res=true
    goto :EOF
)
if %~2==%~1 (
    set res=true
    goto :EOF
)
goto :EOF
Rincewind
  • 31
  • 6
  • 1
    Possible duplicate of [Windows Batch Variables Won't Set](http://stackoverflow.com/questions/9681863/windows-batch-variables-wont-set) – aschipfl Jul 13 '16 at 19:40

2 Answers2

1

Change the first line to echo on and you will see on execution that %res% is replaced by cmd.exe immediately on batch file start by the string false and not changed anymore.

The solution is using setlocal enabledelayedexpansion as explained for example in help of command set which can be viewed by entering in a command prompt window set /?

@echo off
setlocal enabledelayedexpansion
set res=true
Call :IsSame None None1

if false==false (
    echo old: %res%, new: !res!
    Call :IsSame None2 None2
    echo old: %res%, new: !res!
)

GOTO :EOF
:IsSame 
echo isSame
set res=false
if %~2==All (
    set res=true
    goto :EOF
)
if %~2==%~1 (
    set res=true
    goto :EOF
)
goto :EOF

The second line enables now delayed expansion for environment variables.

And there are now twice !res! additionally to %res% to demonstrate the difference between delayed and not delayed expansion. Thanks Stephan for this suggestion.

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • 1
    even better: the echo after the `call` could be: `echo old: %res%, new: !res!` to show both values. – Stephan Jul 07 '14 at 09:12
0

There are a couple of small errors in your code.

@ECHO OFF
SET res=false
CALL :IsSame None None

IF false==false (
    ECHO %res%
    CALL :IsSame None2 None
    ECHO %res%
)

GOTO EOF
:IsSame 
ECHO isSame
SET res = false;
if %~2==All (
    ECHO number1
    SET res=true
    GOTO:EOF
)
if %~2==%~1 (
    SET res=true
    ECHO %res%
    GOTO:EOF
)
GOTO:EOF
:EOF
  • See the Microsoft articles about [goto](http://technet.microsoft.com/en-us/library/bb490914.aspx) and [if](http://technet.microsoft.com/en-us/library/bb490920.aspx) to understand that `goto :EOF` without a label `EOF` is right. And there should be always a space between command `goto` and name of the label without the colon, except for `goto :EOF` although `cmd.exe` interprets also `goto:label` correct. Syntactically 100% correct is nevertheless only `goto label`. – Mofi Jul 07 '14 at 09:30
  • @Mofi, perhaps I am too used to the old-fashioned DOS batch code :) I've always used GOTO:EOF for subroutines because it looked 'cleaner' than GOTO :EOF, which just looks like a mistake in a regular goto command. – Alastair Campbell Jul 07 '14 at 09:43