Geoff Chappell - Software Analyst
Each option begins with a switch character, which can be either a forward slash or hyphen. The standard practice in these notes (as also of the product documentation and of CL itself both for command-line errors and warnings and in the summary produced by the /help option) is to use the forward slash in all references to CL options, leaving it as understood that the hyphen is equivalent unless otherwise stated.
Some CL options that begin with the same letter or letters after the switch character can be combined into one command-line token, with the switch character and common letters given just the once. For example, the sequence of options /Ob2 /Og /Oi /Ot /Oy can be compressed to /Ob2gity. Such combined options are just a convenient shorthand. CL unpicks the combination to recover the individual options, which are thereafter treated as if they actually had been given individually. Only individual options are discussed henceforth. An alphabetical list of individual options is given separately and leads to notes for each option. Those notes assume familiarity with the general notes given here.
Some options have a negation formed by appending a hyphen. Typically, the ordinary option enables some feature and the negation disables it. For example, /GR directs the compiler to emit Run-Time Type Information and /GR- directs it not to. Not all these negations are noted in the product documentation.
A handful of options allow or require a keyword, which is to follow immediately after a colon. Indeed, the only examples are /clr and /Zc. The first may be given alone or as /clr:noAssembly (or with a negation, albeit undocumented). The second is invalid without a keyword (which may be either forScope or wchar_t).
Though these notes set out to treat negations and keywords as variations of the underlying option, presuming this to simplify the concept, it is as well to bear in mind that the implementation actually parses them as separate options. Thus, a /clr or /Zc with a colon and an unrecognised keyword is rejected as an unknown option (with warning D4002), not as an incorrect formulation of a recognised option.
In general, CL options and their keywords are case-sensitive. For example, /GR and /Gr are very different options (one to enable Run-Time Type Information, as noted above, the other to set a default calling convention).
Exceptions are very few. True case-insensitivity applies to just one option, namely /clr (including if given as a negation or with a keyword). One other option, namely /help, is partly case-insensitive in that it is recognised equivalently whether all in lower case or all in upper case.
Some options accept or require an argument. For all except /D, /link, /Tc, /To, /Tp and /U, the parsing of one or more command-line tokens into an option and its argument has a common implementation whose details are given here so that the syntax notes for each option need merely state which case applies.
The following are all the options whose allowance of an argument is subject to these general notes:
/AI, /B1, /B1_5, /B2, /BK, /Bk, /Bl, /Bp1, /Bp2, /Bpl, /Bpx, /Bx, /bC, /bS, /d1, /d1_5, /d2, /F, /FA, /Fa, /Fb, /Fc, /Fd, /Fe, /FI, /Fl, /Fm, /Fo, /FP, /Fp, /FR, /Fr, /Fs, /FU, /f, /GE, /Gp, /Gs, /Gt, /H, /I, /il, /MP, /nl, /OV, /o, /pc, /V, /vd, /W, /w1, /w2, /w3, /w4, /wd, /we, /wo, /Yc, /Yl, /Yu, /YX, /ZB, /Zm, /Zp and /ZX
If an option is not the whole of its command-line token, then the argument can only be the remainder of that same token. Note that the argument begins immediately after the defining characters of the option, including if this means that the argument starts with white space. For example, in the command
cl test.cpp /Fatest.asm
the /Fa option has the argument “test.asm”. CL is to compile the source file “test.cpp” and create an assembly-language listing file named “test.asm” as a by-product. If “test.asm” is the name wanted for the listing file, then there can be no white space after the /Fa, even if quoted: the command
cl test.cpp "/Fa test.asm"
names the listing file as “ test.asm”, with a leading space. Without the quotes, as
cl test.cpp /Fa test.asm
the /Fa and the “test.asm” are separate command-line tokens, and the present rule has nothing to say. It will be seen shortly that the next rule does not apply either, so that /Fa has no argument and “test.asm” names a (second) source file.
For some options, if the option is the whole of its command-line token, then the argument may instead be the whole of the next token. The option then consists of two tokens. For example, in the command
cl test.cpp /FI test.h
the /FI option has “test.h” as its argument, even though the two lie in separate command-line tokens. The unquoted white space between the /FI and the “test.h” could be omitted without changing the interpretation, but may be thought to improve readability.
The applicable options are:
/AI, /B1, /B1_5, /B2, /Bl, /Bp1, /Bp2, /Bpl, /Bpx, /Bx, /bC, /bS, /d1, /d1_5, /d2, /F, /FI, /FU, /f, /H, /I, /il, /MP, /nl, /o, /pc, /V, /W, /w1, /w2, /w3, /w4, /wd, /we and /wo
It happens that for all these, an argument is required, as opposed to being merely permitted.
Some options do not permit their argument to start with a switch character:
/bC, /bS, /F, /FI, /FU, /Gs, /H, /MP, /nl, /V, /vd, /W, /w1, /w2, /w3, /w4, /wd, /we, /wo, /ZB and /Zp
If the command-line token that starts the option continues with a switch character, then the option is deemed to have no argument. The remainder of the token, from the switch character onwards, is ignored without complaint, and no argument is collected from the next token. For example, in the command
cl test.cpp /FI/anything whatever
the /FI has no argument, the /anything in the same command-line token simply never gets interpreted, and the whatever that is the next token is not considered as a possible extension of the /FI option.
If the token that starts the option has no continuation and the option is one of those that can take its argument from the next token but this next token starts with a switch character, then the next token is not deemed part of the option and the option again has no argument. For example, in the command
cl test.cpp /FI /anything
the /FI is alone within its first command-line token but the next token begins with a switch character and cannot extend the /FI option. The /FI therefore has no argument.
Given that an argument is recognised, it is subject to a maximum length, presently 1024 characters. Exceeding this maximum is an error (D2038). Since this applies so generally, it is not mentioned in the syntax notes for particular options. Indeed, the error is so self-explanatory that the product documentation seems not to bother mentioning it anywhere.
For some options, the argument is formally numeric so that again there are common features whose details are given here rather than in the notes for each option:
/F, /Gs, /H, /MP, /nl, /vd, /W, /w1, /w2, /w3, /w4, /wd, /we, /wo, /ZB, /Zm and /Zp
The standard notation for a numerical argument is decimal. It allows for any amount of white space at the start of the argument, including none, and then for a plus or minus sign, before requiring one or more decimal digits. The number that is formed from as many decimal digits as follow is evaluated as an unsigned 32-bit integer. If the number is too large for 32 bits, it is coerced to 0xFFFFFFFF without complaint. The number becomes the numerical value of the argument, except that if a minus sign preceded the number, the value is negated. (A numerical argument that is too large but negative therefore evaluates to 1.)
A handful of options (just /F, /Gs, /H and /nl) permit an additional notation in which a prefix sets the base as octal, decimal or hexadecimal. The prefix is 0x for hexadecimal, 0d or 0t for decimal and 0 alone for octal. The prefix is case-insensitive, as are hexadecimal digits. The prefix is recognised only at the very start of the argument, not after white space. The decimal prefix is in effect discarded, so that the remainder of the argument is interpreted according to the standard notation (with its tolerance of white space, except that this must now follow the prefix rather than begin the argument). The octal and hexadecimal cases do not allow for white space or a sign, but require that the prefix be followed immediately by one or more characters that are valid digits for the selected base. The number formed from these digits is evaluated as an unsigned 32-bit integer. If the number is too large for 32 bits, it is coerced to 0xFFFFFFFF without complaint. The number becomes the numerical value of the argument.
It is an error (D2021) if the argument does not fit the supported notations or continues beyond the number, including with white space. This counts as a general feature of numeric arguments and is not mentioned in the syntax notes for particular options.
It is an error (D2004) if an option that requires an argument is given without one. This also is so general a feature that the syntax notes for particular options take it as implied. Again, it is something that the product documentation seems not to mention anywhere.
Each option may have a list of options that it overrides, another of options it is incompatible with, and another of options that are prerequisites. These lists define the option’s syntactic relations with other options. The compiler builds a set of active options by working through the options as given and applying the relations to determine whether each additional option duplicates, overrides or is incompatible with whatever options have so far been accepted. At the end of this processing, each active option is tested for whether its prerequisites are met among the other active options.
WORK IN PROGRESS
There are non-trivial interactions of option syntax with the minimal-rebuild feature (as enabled by /Gm). However, such interactions are beyond the scope of these notes and seem likely to remain so forever. The author is unaware of sufficient real-world use to justify either the additional study or the intrusion of possibly numerous special cases into the writing up.