Geoff Chappell - Software Analyst
The option is /Ze only.
The /Ze option is enabled by default, being provided by CL as an initial option. Additionally, /Ze
This option passes to the front-end C and C++ compilers (C1 and C1XX) only.
The /Ze option enables numerous variations that Microsoft makes to the language and is pleased to refer to as the Microsoft language extensions. It is a default option, adopted internally by CL and persisting unless the incompatible /Za is given explicitly. The incompatibility is resolved silently by discarding the internal choice.
The variations mostly do extend the language, some by permitting a construction that the standard language does not, and some by investing new meaning in a construction that the standard language either reserves for extension or treats with no particular significance. Both are well established as ways to develop supersets (much as C++ extends C). However, a few of the variations are not extensions at all, but actually disable some feature of the standard language.
Whether they be called extensions or variations, a comprehensive list seems to have exceeded Microsoft’s capability or will, at least as shown by the page titled Microsoft Extensions to C and C++ in the product documentation. The list that develops below, with nothing like the resources that Microsoft ought to have on hand for documenting its own products, will not for a long time be anywhere near complete, nor indeed be more than a random collection of a few features that happen to get written up.
It may be as well to start at Microsoft’s own cue. The language extensions change the set of recognised keywords, both by giving and taking.
Some identifiers become C++ keywords only as part of the language extensions:
__event, __hook, __if_exists, __if_not_exists, __interface, __raise, __super and __unhook
Though each of these keywords gets its own page in the product documentation, none of these pages mention the dependence on /Ze.
When the language extensions are enabled, various keywords that begin with two underscores are also defined as keywords with one leading underscore:
_alignof, _asm, _assume, _based, _builtin_alignof, _cdecl, _compileBreak, _declspec, _except, _export, _far, _far16, _fastcall, _feacpBreak, _finally, _forceinline, _fortran, _huge, _inline, _int16, _int32, _int64 (if /ZB ≥ 64), _int8, _leave, _multiple_inheritance (C++ only), _near, _novtordisp (C++ only), _pascal, _pragma, _ptr32, _ptr64, _serializable, _single_inheritance (C++ only), _stdcall, _syscall, _thiscall (if C++ and -Binl), _transient, _try, _uuidof (C++ only), _virtual_inheritance (C++ only) and _w64
and even with no leading underscore:
cdecl, far, fortran, huge, near and pascal
Support for these one-underscore keywords can be arranged independently via the -ZE option and for the no-underscore keywords (except cdecl) via -Zf. These options are not known to CL.EXE but can be passed to the front-end compilers through /d1.
The C++ language provides that certain operators have alternative representations as keywords. The language extensions defeat this. When /Ze is enabled, the following identifiers are not keywords and have no particular significance:
and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor and xor_eq
When /Ze is active, bool is not a keyword. Unless /noBool is also active, the compiler names bool as the subject of an internal type definition, evaluating to the built-in bool type. The difference from bool being a keyword is surely subtle, which may be why the product documentation leaves it alone.
The language extensions add to the set of characters that are permitted in C++ identifiers. When C++ source text is tokenised, the C++ identifiers are the uninterrupted sequences of letters, digits and underscores, with the digits disallowed for the first character. With /Ze, the $ sign is permitted also.
The product documentation does not mention this extension on either the page titled C++ Identifiers or the list of Microsoft Extensions to C and C++. It may be that Microsoft thinks nobody needs to know of it, because identifiers containing a $ sign are intended as being reserved for Microsoft, as if to extend the standard reservation of identifiers beginning with or containing various sequences involving underscores.
The language extensions tolerate many constructions that the standard language prohibits. What would be an error when compiled with /Za may be relaxed to a warning under /Ze. A warning under /Za may trigger at a higher level under /Ze (i.e., numerically higher, meaning less serious). In some cases, tolerance is complete and a condition that would produce an error or warning under /Za is instead dismissed as being not worth noticing under /Ze.
For the following table of correlations, which is still in development, each error number on the left has at least some case that the language extensions relax to the warning (or warnings) on the right. Three errors under /Za each have at least some case that the language extensions reduce to being not worth even a warning.
Warning and error numbers highlighted yellow are those for which the product documentation, specifically among the C/C++ Build Errors, omits to note the influence of /Za or /Ze, even indirectly by such means as the message text citing use of a “nonstandard extension”. Some omissions are at least careless, if not actually bizarre. For instance, the documentation of warning C4240 seems almost pleased to tell of the Microsoft extensions allowing something that “ANSI compatibility” does not, yet the error (C2331) that this warning displaces is apparently so unimportant that Microsoft doesn’t document it.
|Error with /Za||Warning with /Ze|
|C2059||C4091 (level 2), C4094 (level 2) or C4231 (level 3)|
|C2078||C4207 (level 4)|
|C2133||C4200 (level 2)|
|C2190||C4030 (level 1)|
|C2191||C4031 (level 1)|
|C2192||C4028 (level 1)|
|C2203||C4208 (level 4)|
|C2289||C4114 (level 1)|
|C2328||C4237 (level 1)|
|C2331||C4240 (level 3)|
|C2362||C4533 (level 1)|
|C2370 or C2375||C4211 (level 4)|
|C2467||C4201 (level 4)|
|C2475||C4529 (level 1)|
|C2619||C4203 (level 4) or none|
|C2720||C4630 (level 1)|
|C2901||C4666 (level 1)|
|C2906||C4663 (level 4)|
Some warnings under /Za also change, typically to raise the level or to make it one of the warnings that the compiler disables automatically unless given the /Wall option.
|Warning with /Za||Warning with /Ze|
|C4067 (level 1)||none|
|C4112 (level 1)||C4112 (level 4)|
|C4155 (level 1)||C4156 (level 2)|
|C4223 (level 1)||C4223 (level 4)|
|C4253 (level 1)||C4529 (level 1)|
|C4341 (level 1)||C4341 (level 3)|
There appear to be just two conditions that are treated as more severe when the language extensions are enabled. Whatever condition causes error C2617 is not worth a warning, let alone an error, unless the language extensions are enabled. Warning C4355 ordinarily triggers at level 4 but becomes a level 1 warning under /Ze.