C/C++ Keywords

A keyword is an identifier to which the compiler assigns a formal meaning during tokenisation, such that the identifier is in general reserved for the compiler’s interpretation of the language and is not usable for naming code or data.

Note however that this generality has two broad exceptions. One is provided by the preprocessor: a keyword can be redefined by a macro and thus hidden from the compiler. Another exception is provided by the compiler itself: a keyword can be referred to explicitly as an identifier by giving it as an argument to __identifier (though some need enclosure in double-quotes).

Conditions

Some identifiers become keywords only in some conditions. Many depend on command-line options (most notably /clr, /noBool, /ZB, /Zc:wchar_t and /Ze). Some are keywords in C++ but not in C. Where the table below lists no condition, the identifier is recognised as a keyword by both the C and C++ compilers in all circumstances.

Of the command-line options that affect the list of keywords, -ZE and -Zf are not known to CL.EXE but can be passed to the front-end compiler modules indirectly, via the /d1 option. The term “managed build” is shorthand for any of the C1XX options -Gil, -Gmanaged or -Goptil, the first of which is an ordinary outcome of giving CL the /clr option.

Tokenisation

Though keywords are C/C++ identifiers when examined as text, they do not tokenise as identifiers. See, for instance, that

#pragma message rubbish                 // C4083
#pragma message void                    // C4081

produces two different warnings, the first to complain about the identifier rubbish, the second just about (the token) void.

Among the several hundred types of token recognised by the compiler are many that are dedicated to keywords and operators. Tokenisation maps each keyword to one of these dedicated tokens. Multiple keywords can map to the same token.

The text of a keyword is for all practical purposes lost during tokenisation. Error and warning messages that cite the token show the standard text for that token, which may differ from the text that actually produced the token. For instance, the warning produced by

#pragma message __alignof               // C4081

complains about finding something called __builtin_alignof. Similarly, where a keyword is given as input to __identifier for conversion back to an identifier, the text given for the keyword is long gone and the name produced for the identifier is the standard name of the keyword as a token. For instance, in the function declaration

int __identifier (__alignof) (void *);  // C4932 if /Ze 

the name given to the function is __builtin_alignof. Moreover, the warning, C4932, at level 4 and not raised at all if compiled with /Za, speaks only of confusion over whether __builtin_alignof has one or two leading underscores.

For each keyword, the table below shows the standard text of the corresponding token, if this differs from the text of the keyword.

Disabled Keywords

Many identifiers that are defined as keywords are disabled, as a special case of keyword tokenisation. Every disabled keyword maps to the one token, just for disabled keywords, which gets discarded from the token stream after showing a warning (C4226, C4233, C4234, C4235 or C4236). For instance, in

#pragma message __huge rubbish          // C4226 and C4083

retrieval of the disabled-keyword token that represents the text __huge produces warning C4226, after which __huge may as well have been white space.

Master List of C/C++ Keywords

With keywords acting essentially as reserved words in the language, a master list is surely helpful. In the table below of keywords recognised by Microsoft Visual C++ version 13.00.9466, those that are omitted from the product documentation’s list of C++ Keywords are highlighted yellow. They are not all undocumented: they are just not included in what the documentation seems to present as its master list. Some are mentioned elsewhere in the product documentation, even as keywords. Some are disabled, mostly as being obsolete or unsupported (in this product). All nonetheless are keywords and “cannot be used as identifiers in your program” any more than can the identifiers that Microsoft does happen to list as keywords.

The product documentation lists __m64, __m128, __m128d, __m128i and __noop as keywords. They may be significant to the compiler, and in interesting ways, but they are not actually implemented as keywords and they are therefore not listed as keywords in these notes.

Keyword Conditions to be Keyword Tokenisation
__abstract C++ and managed build  
__alignof   __builtin_alignof
_alignof /Ze or -ZE __builtin_alignof
and C++ and not /Ze &&
and_eq C++ and not /Ze &=
__asm    
_asm /Ze or -ZE __asm
asm C++  
__assume    
_assume /Ze or -ZE __assume
auto    
__based    
_based /Ze or -ZE __based
bitand C++ and not /Ze &
bitor C++ and not /Ze |
bool C++ and neither /noBool nor /Ze  
__box C++ and managed build  
break    
__builtin_alignof    
_builtin_alignof /Ze or -ZE __builtin_alignof
__builtin_isfloat   disabled (warning C4235)
case    
catch C++  
__cdecl    
_cdecl /Ze or -ZE __cdecl
cdecl /Ze __cdecl
char    
class C++  
__compileBreak    
_compileBreak /Ze or -ZE __compileBreak
compl C++ and not /Ze ~
const    
const_cast C++  
continue    
__declspec    
_declspec /Ze or -ZE __declspec
default    
__delegate C++ and managed build  
delete C++  
do    
double    
dynamic_cast C++  
else    
enum    
__event C++ and /Ze  
__except    
_except /Ze or -ZE __except
explicit C++  
__export   disabled (warning C4236)
_export /Ze or -ZE disabled (warning C4236)
extern    
false C++ and not /noBool  
__far   disabled (warning C4226)
_far /Ze or -ZE disabled (warning C4226)
far /Ze or -Zf disabled (warning C4226)
__far16   disabled (warning C4226)
_far16 /Ze or -ZE disabled (warning C4226)
__fastcall    
_fastcall /Ze or -ZE __fastcall
__feacpBreak    
_feacpBreak /Ze or -ZE __feacpBreak
__finally    
_finally /Ze or -ZE __finally
float    
for    
__forceinline    
_forceinline /Ze or -ZE __forceinline
__fortran   disabled (warning C4226)
_fortran /Ze or -ZE disabled (warning C4226)
fortran /Ze or -Zf disabled (warning C4226)
friend C++  
__gc C++ and managed build  
goto    
__hook C++ and /Ze  
__huge   disabled (warning C4226)
_huge /Ze or -ZE disabled (warning C4226)
huge /Ze or -Zf disabled (warning C4226)
__identifier    
if    
__if_exists C++ and /Ze  
__if_not_exists C++ and /Ze  
__inline   inline
_inline /Ze or -ZE inline
inline C++  
int    
__int128   disabled (warning C4235)
__int16    
_int16 /Ze or -ZE __int16
__int32    
_int32 /Ze or -ZE __int32
__int64   if /ZB < 64, disabled (warning C4235)
_int64 /Ze or -ZE, and /ZB ≥ 64 __int64
__int8    
_int8 /Ze or -ZE __int8
__interface C++ and /Ze  
__leave    
_leave /Ze or -ZE __leave
long    
__multiple_inheritance   if C, disabled (warning C4233)
_multiple_inheritance C++ and either /Ze or -ZE __multiple_inheritance
mutable C++  
namespace C++  
__near   disabled (warning C4226)
_near /Ze or -ZE disabled (warning C4226)
near /Ze or -Zf disabled (warning C4226)
new C++  
__nodefault   disabled (warning C4235)
__nogc C++ and managed build  
__nontemporal   disabled (warning C4235)
not C++ and not /Ze !
not_eq and not /Ze !=
__nounwind   disabled (warning C4234)
__novtordisp   if C, disabled (warning C4233)
_novtordisp C++ and either /Ze or -ZE __novtordisp
operator C++  
or C++ and not /Ze ||
or_eq C++ and not /Ze |=
__pascal   disabled (warning C4226)
_pascal /Ze or -ZE disabled (warning C4226)
pascal /Ze or -Zf disabled (warning C4226)
__pin C++ and managed build  
__pragma    
_pragma /Ze or -ZE __pragma
private C++  
__probability   disabled (warning C4235)
__property C++ and managed build  
protected C++  
__ptr32    
_ptr32 /Ze or -ZE __ptr32
__ptr64    
_ptr64 /Ze or -ZE __ptr64
public C++  
__raise C++ and /Ze  
register    
reinterpret_cast C++  
__restrict   disabled (warning C4235)
__resume   disabled (warning C4234)
return    
__sealed C++ and managed build  
__serializable   disabled (warning C4226)
_serializable /Ze or -ZE disabled (warning C4226)
short    
signed    
__single_inheritance   if C, disabled (warning C4233)
_single_inheritance C++ and either /Ze or -ZE __single_inheritance
sizeof    
static    
static_cast C++  
__stdcall    
_stdcall /Ze or -ZE __stdcall
struct    
__super C++ and /Ze  
switch    
__sysapi   disabled (warning C4235)
__syscall   disabled (warning C4226)
_syscall /Ze or -ZE disabled (warning C4226)
template C++  
this C++  
__thiscall   if C, disabled (warning C4234);
if C++ and not -Binl, disabled (warning C4234)
_thiscall C++ and -Binl and either /Ze or -ZE __thiscall
throw C++  
__transient   disabled (warning C4226)
_transient /Ze or -ZE disabled (warning C4226)
true C++ and not /noBool  
__try    
_try /Ze or -ZE __try
try C++  
__try_cast C++  
typedef    
typeid C++  
typename C++  
__typeof C++ and managed build  
__unaligned   disabled (warning C4235)
__unhook C++ and /Ze  
union    
unsigned    
using C++  
__uuidof   if C, disabled (warning C4233)
_uuidof C++ and either /Ze or -ZE __uuidof
__value C++ and managed build  
virtual C++  
__virtual_inheritance   if C, disabled (warning C4233)
_virtual_inheritance C++ and either /Ze or -ZE __virtual_inheritance
void    
volatile    
__w64    
_w64 /Ze or -ZE __w64
__wchar_t    
wchar_t C++ and /Zc:wchar_t __wchar_t
while    
xor C++ and not /Ze ^
xor_eq C++ and not /Ze ^=