Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Conditional inclusion

      From cppreference.com
      <cpp‎ |preprocessor
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Preprocessor
      #if#ifdef#ifndef#else#elif#elifdef#elifndef#endif
      (C++23)(C++23)
      (C++26)
       

      The preprocessor supports conditional compilation of parts of source file. This behavior is controlled by#if,#else,#elif,#ifdef,#ifndef,#elifdef,#elifndef(since C++23), and#endif directives.

      Contents

      [edit]Syntax

      #ifexpression
      #ifdefidentifier
      #ifndefidentifier
      #elifexpression
      #elifdefidentifier(since C++23)
      #elifndefidentifier(since C++23)
      #else
      #endif

      [edit]Explanation

      The conditional preprocessing block starts with#if,#ifdef or#ifndef directive, then optionally includes any number of#elif,#elifdef, or#elifndef(since C++23) 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,#ifdef,#ifndef,#elif,#elifdef,#elifndef(since C++23), and#else directives control the code block until the first#elif,#elifdef,#elifndef(since C++23),#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,#elifdef,#elifndef,(since C++23) and#elif directives are ignored. Otherwise, if the specified condition evaluates false, the controlled code block is skipped and the subsequent#else,#elifdef,#elifndef,(since C++23) or#elif directive (if any) is processed. If the subsequent directive is#else, the code block controlled by the#else directive is unconditionally compiled. Otherwise, the#elif,#elifdef, or#elifndef(since C++23) 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,#elifdef,#elifndef,(since C++23) and#else directives. The conditional preprocessing block is terminated by#endif directive.

      [edit]Condition evaluation

      [edit]#if, #elif

      expression may contain unary operators in formdefined identifier ordefined (identifier). The result is1 if theidentifier wasdefined as a macro name, otherwise the result is0.

      expression may also contain the following expressions:

      • __has_include expressions, which detects whether a header or source file exists.
      • __has_cpp_attribute expressions, which detects whether a given attribute token is supported and its supported version.
      (since C++20)
      • __has_embed expressions, which detects whether a resource is available to be embedded.
      (since C++26)

      The identifiers mentioned above are treated as if they were the names of defined macros in this context.

      (since C++17)

      After all macro expansion and evaluationdefined and the expressions described above, any identifier which is not aboolean literal is replaced with the number0 (this includes identifiers that are lexically keywords, but not alternative tokens likeand).

      Then the expression is evaluated as anintegral constant expression.

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

      Note: Until the resolution ofCWG issue 1955,#ifcond1 ...#elifcond2 is different from#ifcond1 ...#else followed by#ifcond2 because ifcond1 is true, the second#if is skipped andcond2 does not need to be well-formed, while#elif'scond2 must be a valid expression. As of CWG 1955,#elif that leads the skipped code block is also skipped.

      [edit]Combined directives

      Checks if the identifier wasdefined as a macro name.

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

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

      #elifdef identifier is essentially equivalent to#elif defined identifier.

      #elifndef identifier is essentially equivalent to#elif !defined identifier.

      (since C++23)

      [edit]Notes

      While#elifdef and#elifndef directives target C++23, implementations are encouraged to backport them to the older language modes as conforming extensions.

      [edit]Example

      Run this code
      #define ABCD 2#include <iostream> int main(){ #ifdef ABCDstd::cout<<"1: yes\n";#elsestd::cout<<"1: no\n";#endif #ifndef ABCDstd::cout<<"2: no1\n";#elif ABCD == 2std::cout<<"2: yes\n";#elsestd::cout<<"2: no2\n";#endif #if !defined(DCBA) && (ABCD < 2*4-3)std::cout<<"3: yes\n";#endif  // Note that if a compiler does not support C++23's #elifdef/#elifndef// directives then the "unexpected" block (see below) will be selected.#ifdef CPUstd::cout<<"4: no1\n";#elifdef GPUstd::cout<<"4: no2\n";#elifndef RAMstd::cout<<"4: yes\n";// expected block#elsestd::cout<<"4: no!\n";// unexpectedly selects this block by skipping// unknown directives and "jumping" directly// from "#ifdef CPU" to this "#else" block#endif // To fix the problem above we may conditionally define the// macro ELIFDEF_SUPPORTED only if the C++23 directives// #elifdef/#elifndef are supported.#if 0#elifndef UNDEFINED_MACRO#define ELIFDEF_SUPPORTED#else#endif #ifdef ELIFDEF_SUPPORTED#ifdef CPUstd::cout<<"4: no1\n";#elifdef GPUstd::cout<<"4: no2\n";#elifndef RAMstd::cout<<"4: yes\n";// expected block#elsestd::cout<<"4: no3\n";#endif#else // when #elifdef unsupported use old verbose “#elif defined”#ifdef CPUstd::cout<<"4: no1\n";#elif defined GPUstd::cout<<"4: no2\n";#elif !defined RAMstd::cout<<"4: yes\n";// expected block#elsestd::cout<<"4: no3\n";#endif#endif}

      Possible output:

      1: yes2: yes3: yes4: no!4: yes

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1955C++98failed#elif's expression was required to be validfailed#elif is skipped

      [edit]See also

      C documentation forConditional inclusion
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/preprocessor/conditional&oldid=182193"

      [8]ページ先頭

      ©2009-2025 Movatter.jp