# Conditional inclusion

From cppreference.com
< cpp‎ | preprocessor

The preprocessor supports conditional compilation of parts of source file. This behavior is controlled by `#if`, `#else`, `#elif`, `#ifdef`, `#ifndef` and `#endif` directives.

### Syntax

`#if` expression |  |
`#ifdef` identifier |  |
`#ifndef` identifier |  |
`#elif` expression |  |
`#else` |  |
`#endif` |  |

### Explanation

The conditional preprocessing block starts with `#if`, `#ifdef` or `#ifndef` directive, then optionally includes any number of `#elif` directives, then optionally includes at most one `#else` directive and is terminated with `#endif` directive. Any inner conditional preprocessing blocks are processed separately.

Each of `#if`, `#elif`, `#else`, `#ifdef` and `#ifndef` directives control code block until first `#elif`, `#else`, `#endif` directive not belonging to any inner conditional preprocessing blocks.

`#if`, `#ifdef` and `#ifndef` directives test the specified condition (see below) and if it evaluates to true, compiles the controlled code block. In that case subsequent `#else` and `#elif` directives are ignored. Otherwise, if the specified condition evaluates false, the controlled code block is skipped and the subsequent `#else` or `#elif` directive (if any) is processed. In the former case, the code block controlled by the `#else` directive is unconditionally compiled. In the latter case, the `#elif` directive acts as if it was `#if` directive: checks for condition, compiles or skips the controlled code block based on the result, and in the latter case processes subsequent `#elif` and `#else` directives. The conditional preprocessing block is terminated by `#endif` directive.

### Condition evaluation

#### `#if, #elif`

The expression is a constant expression.

The expression may contain unary operators in form `defined` identifier or `defined (`identifier`)`. The result is 1 if the identifier was defined as a macro name or the identifier is `__has_include` (since C++17), otherwise the result is ​0​.

After all macro expansion and evaluation of `defined` and `__has_include` (since C++17) expressions, any identifier which is not a boolean literal is replaced with the number ​0​ (this includes identifiers that are lexically keywords, but not alternative tokens like `and`).

If the expression evaluates to nonzero value, the controlled code block is included and skipped otherwise.

Note: `#if cond1` ... `#elif cond2` is different from `#if cond1` ... `#else` followed by `#if cond3` because if `cond1` is true, the second `#if` is skipped and `cond3` does not need to be well-formed, while #elif's `cond2` must be a valid expression. | (until C++14)

#### `#ifdef, #ifndef`

Checks if the identifier was defined as a macro name.

`#ifdef` identifier is essentially equivalent to `#if defined` identifier``.

`#ifndef` identifier is essentially equivalent to `#if !defined` identifier``.

### Example

Run this code

    #define ABCD 2
    #include <iostream>

    int main()
    {

    #ifdef ABCD
        std::cout << "1: yes\n";
    #else
        std::cout << "1: no\n";
    #endif

    #ifndef ABCD
        std::cout << "2: no1\n";
    #elif ABCD == 2
        std::cout << "2: yes\n";
    #else
        std::cout << "2: no2\n";
    #endif

    #if !defined(DCBA) && (ABCD < 2*4-3)
        std::cout << "3: yes\n";
    #endif
    }

Output:

    1: yes
    2: yes
    3: yes

### Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR | Applied to | Behavior as published | Correct behavior
--- | --- | --- | ---
CWG 1955 | C++14 | failed #elif's expression was required to be valid | failed elif is skipped

### See also

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/preprocessor/conditional&oldid=102387"