Erratic IF behavior

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

rconn

Administrator
Staff member
May 14, 2008
10,101
85
#1
There are two undocumented bugs / (unfeatures?) in the IF command in CMD.EXE.

CMD's behavior with IF is to ignore everything else on a command line if the IF fails. This is undocumented, which is one reason I consider it a "bug" -- the second being that it's senseless to treat something following a command separator (&) as being somehow syntactically related to the previous command. (Why not have FOR ignore compound commands if it fails??) If the user wants to evaluate the IF result conditionally, they should be using the && or || operators.

Unfortunately, an number of batch files written for CMD rely on this behavior (sometimes as a unnecessary hack, and sometimes because the author apparently didn't know any better).

The second "unfeature" is when IF is used in a multiline command group. CMD assembles a command group into a single compound command by adding a command separator (&) before each line. The inconsistency is that it treats an end of line within a command group as (slightly) different from a & -- but only for IF! (It resets its internal flag that would otherwise have it ignore the remainder of the line).
 
Nov 2, 2008
177
0
#2
It's a carry over from basica.

Still, i suppose 4DOS had its run before it had to deal with benny-levels! This works under most versions of command.com, but not under cmd.exe

Code:
@ECHO OFF
::  Benny Penderson, "Hex-Hax" of the year of the Lord, 19;3.
choice /n /cABCDEFGHIJKLMNOPQRSTUVWXYZ Choose drive:
:  FINDCD
FOR %%D IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF ERRORLEVEL H%%D SET DRIVE=%%D
ECHO You chose drive %DRIVE%
 
FOR %%D IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO IF ERRORLEVEL x%%D SET DRIVE=%%D
ECHO You chose drive %DRIVE%
The 'year of the Lord' thing is a Y2k bug that replicates what's going on here. It's looking at a number ((asc(H)-asc(0))*10 + (asc(A)-asc(0)))mod256.