Device Monitoring Studio - Monitor, log and analyze data coming through PC ports and connections
Download Device Monitoring Studio Hide this button

Conditional Compilation Directives

#if, #elif, #else, #endif, defined() operator

The #if directive, with the #elif, #else, and #endif directives, controls compilation of portions of a source file. If the expression you write (after the #if) has a nonzero value, the line group immediately following the #if directive is retained in the translation unit.

#if expression
text
[
#elif expression
text
[
#elif expression
text
]]
[
#else
text
]
#endif

Each #if directive in a source file must be matched by a closing #endif directive. Any number of #elif directives can appear between the #if and #endif directives, but at most one #else directive is allowed. The #else directive, if present, must be the last directive before #endif.

The #if, #elif, #else, and #endif directives can nest in the text portions of other #if directives. Each nested #else, #elif, or #endif directive belongs to the closest preceding #if directive.

All conditional-compilation directives, such as #if and #ifdef, must be matched with closing #endif directives prior to the end of file; otherwise, an error message is generated. When conditional-compilation directives are contained in include files, they must satisfy the same conditions: There must be no unmatched conditional-compilation directives at the end of the include file.

Macro replacement is performed within the part of the command line that follows an #elif command, so a macro call can be used in the expression.

The preprocessor selects one of the given occurrences of text for further processing. A block specified in text can be any sequence of text. It can occupy more than one line. Usually text is program text that has meaning to the compiler or the preprocessor.

The preprocessor processes the selected text and passes it to the compiler. If text contains preprocessor directives, the preprocessor carries out those directives. Only text blocks selected by the preprocessor are compiled.

The preprocessor selects a single text item by evaluating the constant expression following each #if or #elif directive until it finds a true (nonzero) constant expression. It selects all text (including other preprocessor directives beginning with #) up to its associated #elif, #else, or #endif.

If all occurrences of constant-expression are false, or if no #elif directives appear, the preprocessor selects the text block after the #else clause. If the #else clause is omitted and all instances of constant-expression in the #if block are false, no text block is selected.

The constant-expression is an integer constant expression with these additional restrictions:

The preprocessor operator defined can be used in special constant expressions, as shown by the following syntax:

defined(identifier)
defined identifier

This constant expression is considered true (nonzero) if the identifier is currently defined; otherwise, the condition is false (0). An identifier defined as empty text is considered defined. The defined directive can be used in an #if and an #elif directive, but nowhere else.

// Define the structure definition variant:
#define VARIANT 2

// …

struct A
{
#if VARIANT == 1
    char a;
#elif VARIANT == 2
    short a;
#elif VARIANT == 3
    int a;
#else
    long a;
#endif
};

#ifdef, #ifndef

The #ifdef and #ifndef directives perform the same task as the #if directive when it is used with defined(identifier).

#ifdef identifier
#ifndef identifier

// equivalent to
#if defined(identifier)
#if !defined(identifier)

You can use the #ifdef and #ifndef directives anywhere #if can be used. The #ifdef identifier statement is equivalent to #if 1 when identifier has been defined, and it is equivalent to #if 0 when identifier has not been defined or has been undefined with the #undef directive. These directives check only for the presence or absence of identifiers defined with #define.