The #pragma Directive

Syntax

#pragma [ pragma [ argument-list ]]

The general syntax of preprocessor directives applies up to and including pragma. Though it is the convention of these notes to write #pragma as one unit, remember that there may be any amount of white space, including none, before and after the # sign.

Beyond the #pragma, the directive is interpreted as a stream of tokens continuing to the end of the line. Very little interpretation occurs if the compiler is limited to preprocessing (as by the /E, /EP or /P options). Details are given separately below. No interpretation at all occurs if the /Zg option is active: any line that begins with a #pragma directive is simply ignored.

A #pragma directive that is alone on its line is trivial. Otherwise, the first token is expected to be an identifier, represented above by the pragma placeholder.

Generally speaking, a #pragma directive with incorrect syntax is ignored, except for a warning (C4081 or C4083). The warning tells what type of token was expected and what type was found instead. If what was found is an identifier, it is reproduced in the message text. All remaining tokens to the end of the line are then ignored. This treatment of incorrect syntax begins with deciding whether pragma is an identifier. The intention in these notes is to leave this treatment as understood for any case in which the stated syntax is not satisfied but no other treatment is specified. Also left as understood even for other conditions that attract a warning is that the directive is then ignored by discarding the remaining tokens on the line.

The meaning of a #pragma directive depends on which of many expected values are given for pragma. An unrecognised pragma causes a warning (C4068) at level 1.

It is conventional to talk of a #pragma directive with a particular pragma as a pragma and of any tokens that follow as this pragma’s argument-list.

Though implemented within the language as preprocessor directives, only very few pragmas are acted on immediately by the preprocessor (namely, implementation_key, include_alias and start_map_region). In all other cases, the preprocessor instead tokenises the pragma for action by the compiler. Specifically, it creates one token to represent the pragma as a “compile time directive” and has this token carry as its value a token stream that represents the pragma’s argument-list. This handling is how most pragmas can be given equivalently as preprocessor directives or through the compiler’s __pragma keyword.

Recognised Pragmas

In the following lists of syntactically valid keywords for the #pragma directive in Microsoft Visual C++ version 13.00.9466, those that are omitted from the list titled Pragma Directives in the product documentation are highlighted yellow. Some others, though documented, have undocumented features.

The following are syntactically valid, but produce the “unknown pragma” warning (C4068) at level 4:

Some more syntactically valid keywords also generate the “unknown pragma” warning (C4068), but at level 1, just as if unrecognised:

Note however that acp_assume_not_defined, acp_assume_not_type, acp_assume_type and acp_store are meaningful to the Front-End Auto-Complete Parser (FEACP).