Namespaces
Variants
Views
Actions

Conditional inclusion

From cppreference.com
< cpp‎ | preprocessor
Revision as of 00:47, 26 March 2013 by 149.62.146.102 (Talk)

 
 
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 Template:sparam
#ifdef Template:sparam
#ifndef Template:sparam
#elif Template:sparam
#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 Template:sparam is a constant expression, using only literals and identifiers, defined using Template:rlpt directive. Any identifier, which is not literal, non defined using Template:rlpt directive, evaluates to 0.

The expression may contain unary operators in form defined Template:sparam or defined (Template:sparam) which return 1 if the Template:sparam was defined using Template:rlpt directive and 0 otherwise. If the Template:sparam 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 Template:rlpt directive.

#ifdef Template:sparam is essentially equivalent to #if defined( Template:sparam).

#ifndef Template:sparam is essentially equivalent to #if !defined( Template:sparam).

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