Nested IF syntax — TCC behaving differently to CMD

The following code comes from "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd", a Microsoft SDK batch file.
Code:
IF "x%TARGET_CPU%x"=="xx" (
IF /I "%PROCESSOR_ARCHITECTURE%"=="x86" SET "TARGET_CPU=x86" & SET "CURRENT_CPU=x86"
IF /I "%PROCESSOR_ARCHITEW6432%"=="x86" SET "TARGET_CPU=x86" & SET "CURRENT_CPU=x86"
IF /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" SET "TARGET_CPU=x64" & SET "CURRENT_CPU=x64"
IF /I "%PROCESSOR_ARCHITEW6432%"=="AMD64" SET "TARGET_CPU=x64" & SET "CURRENT_CPU=x64"
IF /I "%PROCESSOR_ARCHITECTURE%"=="x64"   SET "TARGET_CPU=x64" & SET "CURRENT_CPU=x64"
IF /I "%PROCESSOR_ARCHITECTURE%"=="IA64"  SET "TARGET_CPU=IA64" & SET "CURRENT_CPU=IA64"
IF /I "%PROCESSOR_ARCHITEW6432%"=="IA64"  SET "TARGET_CPU=IA64" & SET "CURRENT_CPU=IA64"
GOTO Parse_Args
)
(on my machine, it is the 3rd inner IF that triggers.)

Under CMD, this code sets TARGET_CPU and CURRENT_CPU.
Under TCC, this code sets none of the variables.

The following code (only the 3rd inner IF, not nested)
Code:
IF /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" SET "TARGET_CPU=x64" & SET "CURRENT_CPU=x64"
sets TARGET_CPU and CURRENT_CPU both under CMD and TCC.

TCC 21.00.32 x64 Windows 7 [Version 6.1.7601]
 
Last edited:
May 20, 2008
11,530
102
Syracuse, NY, USA
Here's a simplified version. It shows an apparent bug where v21 (in comparison to v20) seems to terminate the () grouping early. V20 acts more sanely, but still not like CMD.
Code:
v:\> type iffy.bat
@echo off
if "1"=="1" (
echo 1
if "%zz%"=="a" echo zz=a & echo zz=a
echo 2
if "%zz%"=="b" echo zz=b & echo zz=b
)
Here are the three, v21 ...
Code:
v:\> ver & set zz=a & iffy.bat

TCC  21.00.32   Windows 7 [Version 6.1.7601]
1
zz=a
zz=a
2

v:\> ver & set zz=b & iffy.bat

TCC  21.00.32   Windows 7 [Version 6.1.7601]
1
v20 ...
Code:
v:\> ver & set zz=a & iffy.bat

TCC  20.11.46   Windows 7 [Version 6.1.7601]
1
zz=a
zz=a
2
zz=b

v:\> ver & set zz=b & iffy.bat

TCC  20.11.46   Windows 7 [Version 6.1.7601]
1
zz=a
2
zz=b
zz=b
CMD ...
Code:
V:\> ver

Microsoft Windows [Version 6.1.7601]

V:\> set zz=a

V:\> iffy.bat
1
zz=a
zz=a
2

V:\> set zz=b

V:\> iffy.bat
1
2
zz=b
zz=b
 
May 20, 2008
11,530
102
Syracuse, NY, USA
Turn off "Duplicate CMD.EXE bugs".
OK, that makes v21 act like v20. But (though it doesn't bother me) TCC and CMD still treat this differently.
Code:
if 1==2 echo foo & echo bar
I recall this being discussed ib the past but I don't remember the bottom line.
 

rconn

Administrator
Staff member
May 14, 2008
12,404
152
OK, that makes v21 act like v20. But (though it doesn't bother me) TCC and CMD still treat this differently.
Code:
if 1==2 echo foo & echo bar
I recall this being discussed ib the past but I don't remember the bottom line.

For that, you have to turn "Duplicate CMD.EXE bugs" back on. CMD will not process additional commands if the IF fails (which is undocumented, and obviously wrong behavior).
 
May 20, 2008
11,530
102
Syracuse, NY, USA
A sensible (?) interpretation is that CMD's
Code:
if condition command1 & command 2
is the same as TCC's
Code:
if condition (command1 & command2)

That's how CMD behaves and it seems to be the intent in the BATfile from the original post in this thread.
 

rconn

Administrator
Staff member
May 14, 2008
12,404
152
A sensible (?) interpretation is that CMD's
Code:
if condition command1 & command 2
is the same as TCC's
Code:
if condition (command1 & command2)

That's how CMD behaves and it seems to be the intent in the BATfile from the original post in this thread.

That would be sensible - except that (1) it's undocumented, and (2) CMD also supports command groups, so if you wanted it to ignore compound commands you could just use a command group. Having it act like that only for IF makes no sense.
 
  • Like
Reactions: evensenm

rconn

Administrator
Staff member
May 14, 2008
12,404
152
Here's a simplified version. It shows an apparent bug where v21 (in comparison to v20) seems to terminate the () grouping early. V20 acts more sanely, but still not like CMD.

TCMD v21 and v20 behave exactly the same, provided you have the "Duplicate CMD.EXE bugs" set the same in both (apparently you didn't).
 
Jul 29, 2016
49
1
I haven't tried any of the above examples myself, but looking at what was posted above, it looks like TCC's behavior (with "Duplicate CMD Bugs" turned ON) is still different than CMD's behavior when it comes to *NESTED* IF statements (with the "outer" IF statement command(s) to execute being in a command group with ()'s ). Without nested IF statements and just a single IF statement with compound commands, it looks like TCC's behavior (with "Duplicate CMD Bugs" turned ON) and CMD's behavior are the same, as what I would expect with "Duplicate CMD Bugs" turned ON. It appears to be an issue with *NESTED* IF statements. Look at vefatica's first example again between TCC v21 and CMD (it's evident to me that his v21 is with "Duplicate CMD Bugs" turned ON). Again, I haven't personally tested, but am just making an observation on the output of the commands posted above.
 
Last edited:
Jul 29, 2016
49
1
This is an issue in TCC that is inconsistent with what the documentation states.

The documentation for the IF command states (excerpt):

When an IF test fails, the remainder of the command is discarded. Whether TCC continues with the next command on the line, or discards the rest of the line and goes to the next line is dependent upon the Duplicate CMD Bugs configuration option. CMD will discard all remaining commands on the line when an IF test fails, including those after a command separator or pipe character. If you do not want to reproduce CMD.EXE's behavior of an IF affecting all commands on a line, set DuplicateBugs to No in the .INI file. The IF behavior is different when DuplicateBugs is YES in a command group in a batch file. If there are multiple command lines in the command group, a failed IF will only ignore the remainder of the commands on that line. The commands on the subsequent lines in the command group will still be executed.

Note that it states that even with DuplicateBugs set to YES, a failed IF will only ignore the rest of the commands on that line (presumably separated with the command separator & ), and that the separate remaining lines in the command group will still be executed. TCC is clearly not doing that when "Duplicate CMD Bugs" is turned ON. All the remaining commands in the command group, even all the ones on separate lines, are discarded. Check this out:

Code:
C:\Users\Mark\Documents\test 4>type iffy.bat

@echo off

if "foo" == "foo" (
    echo Line 1
    if "%zz%" == "a" echo zz=a & echo zz=a
    echo Line 2
    if "%zz%" == "b" echo zz=b & echo zz=b
    echo Next to Last Line
)

echo Last Line

Under TCC, this is shown when zz=a

Code:
C:\Users\Mark\Documents\test 4>iffy

Line 1
zz=a
zz=a
Line 2
Last Line

And when zz=b ....

Code:
C:\Users\Mark\Documents\test 4>iffy

Line 1
Last Line

And under CMD.....
zz=a
Code:
C:\Users\Mark\Documents\test 4>iffy

Line 1
zz=a
zz=a
Line 2
Next to Last Line
Last Line

zz=b
Code:
C:\Users\Mark\Documents\test 4>iffy
Line 1
Line 2
zz=b
zz=b
Next to Last Line
Last Line
 
May 20, 2008
11,530
102
Syracuse, NY, USA
This is an issue in TCC that is inconsistent with what the documentation states.
The documentation for the IF command states (excerpt):
Maybe this will shed some light on the problem. By mistake, I omitted a quote in the first of the nested IFs.
Code:
v:\> type iffy2.bat
IF "1"=="2" (
IF %zz"=="a" echo zz=a & echo zz=a
IF "%zz"=="b" echo zz=b & echo zz=b
IF "%zz"=="c" echo zz=c & echo zz=c
)
v:\>
And, with DuplicateBuge=Yes, I get this.
Code:
v:\> iffy2.bat
TCC: V:\iffy2.bat [6]  Unbalanced parentheses "IF "1"=="2" ( IF %zz"=="a" echo zz=a & echo zz=a &| IF "%zz"=="b"
echo zz=b & echo zz=b &| IF "%zz"=="c" echo zz=c & echo zz=c ) "
TCC: V:\iffy2.bat [7]  Unbalanced parentheses "( IF %zz"=="a" echo zz=a & echo zz=a &| IF "%zz"=="b" echo zz=b &
echo zz=b &| IF "%zz"=="c" echo zz=c & echo zz=c ) "
V:\iffy2.bat [7]  Usage : IF [/I] [NOT] condition [.AND. | .OR. | .XOR. [NOT] condition ...] command

First, what's "&|"? Guessing that it's an internal construct for implementing DuplicateBugs and delineating the actual batch file lines, the intended (?) strategy seems sound ... when the condition is false, go to the next line. But it doesn't seem to be doing that.[/QUOTE]
 

rconn

Administrator
Staff member
May 14, 2008
12,404
152
This issue isn't actually about nested IF statements (which TCC handles fine), it's about what to do when a (badly-written) CMD-compatible batch file inserts additional non-IF statements inside a command group in an IF. I have made a change to 21.0.33 to match CMD's highly-erratic (and undocumented, and flat out wrong) behavior if you have the "Duplicate CMD bugs" enabled.
 
Thanks for the change.
I agree the syntax is awful.
I have "Duplicate CMD bugs" enabled — but I seldom bump into the category of problems this check addresses (my own scripts are obviously written in clear TCC syntax), and I didn't make the connection.
 
Similar threads
Thread starter Title Forum Replies Date
C CMD's "nested quote" syntax Support 3
B Problem with color in nested shells Support 1
R Problem with %_do_loop in nested do loops Support 2
C FOR loop with nested IF / IFF Support 9
jbanaszczyk Broken For and nested Do Support 2
vefatica _DO_LOOP and nested DOs? Support 8
vefatica WAD Nested variable expansion in PDIR's @function[*]? Support 13
vefatica Single-line DO inside nested multi-line DOs? Support 9
R How to? debug a nested batch file Support 2
G WAD Nested if exits enclosing if Support 3
M A problem with nested Gosub's/ExecStr's Support 14
dcantor Terminology question: nested vs. recursive Support 0
R nested for loop question Support 3
J Nested for loops and quotes Support 12
D can PDIR list full filepaths of docs in a nested folder? Support 13
M syntax for sftp with publickey Support 3
vefatica IDE external command syntax color? Support 1
Joe Caverly Command Input Syntax Colouring Support 3
rps Documentation Regular expression syntax link broken Support 1
Dan Glynhampton Documentation v15 help: Syntax error in example of @DEC Support 0
D Syntax error when redirecting eval Support 5
C @diskfree[ ] syntax in 15.00.17 Support 0
T Syntax highlighting in the IDE Support 8
cgunhouse Eventlog Syntax issue Support 8
krischik Stop Script after Syntax Error. Support 6
J syntax problems multiple commands (command & command) Support 4
T TCTOOLBAR syntax Support 0
S Status line syntax help Support 2
H Double prompt for password with * in FTP syntax Support 3
dcantor FFIND syntax -- is /E"regex" /X supported? Support 2
C extended DIR syntax? Support 7
J Problem with %var:find=replace% syntax Support 5
A syntax colouring Support 0
dcantor Syntax files, and suggestion Support 0
J Problem with peculiar CMD syntax Support 2
A Can you set an image file 'tag' with TCC/4NT? Support 0
P PSHELL not working in TCC 26 Support 9
vefatica SCRIPT makes TCC disappear. Support 16
MickeyF TCC suddenly crashing (not TCC's fault) Support 2
Z CMDDebug - TCC unknown command Support 2
rconn News Take Command / TCC / CMDebug / TCC-RT 28.02.17 Support 0
vefatica TCC startup: /IP not honored after /K Support 1
MickeyF TCC crashing when copying multiple files (now resolved) Support 6
C COMSPEC constantly reset to TCC.EXE Support 6
rconn News Take Command / TCC / CMDebug / TCC-RT v28 Released Support 0
C How to? starting TCC/TCMD v25 Support 2
CWBillow TCC and TCMD in Powershell Support 6
rconn News Take Command / TCC / CMDebug / TCC-RT 27.01.24 uploaded Support 0
rconn News Take Command / TCC / CMDebug / TCC-RT 27.01.23 uploaded Support 0
Alpengreis Fixed Crash after copy dialog with big TCC.exception.log Support 5

Similar threads