6

I've noticed in a windows batch file, even if you REM out a %~ you get the error

For valid formats type CALL /? or FOR /?
The syntax of the command is incorrect.

Why isn't the commented line ignored?

@ ECHO OFF
REM Blah blah blah
REM %~ this will cause an error
REM %%~ Double the fun, no error
Mr Mystery Guest
  • 1,464
  • 1
  • 18
  • 47
  • Try the same comments directly in command prompt and you will see there is no error; this shows that the `%~` part is truly related to [command line argument expansion](http://ss64.com/nt/syntax-args.html) of batch files... – aschipfl Jun 14 '17 at 13:30
  • Also try the following: `rem %var:=`; this will fail in command prompt and in batch files, given that the variable `var` is defined; this shows the error is linked to [environment variable expansion (sub-string replacement)](http://ss64.com/nt/syntax-replace.html)... – aschipfl Jun 14 '17 at 13:36

3 Answers3

5

REM is a command like ECHO. Run in a command prompt window rem /? to get help on this command.

The Windows command interpreter first parses this command line like all other lines in a batch file with the exception of those lines starting with a colon which are interpreted as label line and not as command line.

So a single % is interpreted as begin of an environment variable or batch file argument reference before REM is executed at all. The single percent sign is removed because there is no more percent sign on this command line.

%~ is interpreted on command line parsing as invalid batch file argument reference. That the command REM does not evaluate the rest of the line does not matter for Windows command interpreter. First the command line is parsed independent on the command and next the command is executed by cmd.exe whatever the command is.

Remove first line @ ECHO OFF and it can be seen how each command line is executed after being parsed by Windows command interpreter. Lines starting with a colon are not output as being interpreted as label line instead of a command line.

For details about batch script parsing see How does the Windows Command Interpreter (CMD.EXE) parse scripts?

Example:

REM User name: %USERNAME%
REM User profile directory: %USERPROFILE%
REM Application data directory: %APPDATA%
REM Batch arguments: %0 %*
PAUSE

The environment variable references and the batch file arguments reference in those REM command lines are replaced by the values of the environment variables and the batch file arguments on running this batch file without @ECHO OFF at top.

Mofi
  • 46,139
  • 17
  • 80
  • 143
4

the (initially) posted code will not cause an error. But this will:

REM %~ this will cause an error

The reason is that the argument expansions is with higher priority than the comments and cmd.exe will try first to expand and dequote the not given argument here %~

npocmaka
  • 55,367
  • 18
  • 148
  • 187
  • You're right, no error. Although I got an error somewhere along the line otherwise I wouldn't have asked this question. Little bit confused right now :) – Mr Mystery Guest Jun 14 '17 at 09:32
  • @MrMysteryGuest - the only way to produce error described above is to mess some how with the arguments passed to the script or a subroutine. But without more code I cant say more. – npocmaka Jun 14 '17 at 09:40
  • Thanks. I was deleting my script character by character till I didn't get the error. I didn't try it from a fresh DOS window which may have been causing further problems – Mr Mystery Guest Jun 14 '17 at 09:43
0

Best way to avoid the expansion REM statement arguments is to jump over them with a goto. Something like this:

    goto :afterREMS
    REM following line with crash/exit the BAT script if processed
    REM     %~I         - expands %I removing any surrounding quotes (")
    :afterREMS

Been programming for quite a while and today was the first time I got bitten by this issue. I thought it would be handy to document all the different macro expansions in my BAT, but ran into this issue.