Namespaces
Variants
Views
Actions

Conditional inclusion

From cppreference.com
< cpp‎ | preprocessor
Revision as of 11:28, 15 August 2013 by P12 (Talk | contribs)

 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 
 

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

Contents

Syntax

#if expression
#ifdef expression
#ifndef expression
#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, using only literals and identifiers, defined using #define directive. Any identifier, which is not literal, non defined using

  1. define directive, evaluates to 0.

The expression may contain unary operators in form defined identifier or defined (identifier) which return 1 if the identifier was defined using #define directive and 0 otherwise. If the expression evaluates to nonzero value, the controlled code block is included and skipped otherwise. If any used identifier is not a constant, it is replaced with 0.

#ifdef, #ifndef

Checks if the identifier was defined using #define directive.

#ifdef identifier is essentially equivalent to #if defined( identifier).

#ifndef identifier is essentially equivalent to #if !defined( identifier).

Example

#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