Conditional inclusion
条件包含
预处理器支持源文件部分的条件编译。这种行为由#if
,,,#else
,,,#elif
,,,#ifdef
,,,#ifndef
和#endif
指令。
句法
#if expression | | |
---|---|---|
#ifdef expression | | |
#ifndef expression | | |
#elif expression | | |
#else | | |
#endif | | |
解释
条件预处理块以#if
,,,#ifdef
或#ifndef
指令,则可以选择包含任意数量的#elif
指令,则最多包含一个指令。#else
指令,并以#endif
指令。任何内部条件预处理块都分别处理。
每一个#if
,,,#elif
,,,#else
,,,#ifdef
和#ifndef
指令控制代码块直到第一个#elif
,,,#else
,,,#endif
指令不属于任何内部条件预处理块。
#if
,,,#ifdef
和#ifndef
指令测试指定的条件%28(见%29下面),如果其计算结果为true,则编译受控代码块。在这种情况下,后继#else
和#elif
指令被忽略。否则,如果指定的条件计算为false,则跳过受控代码块,然后跳过后续代码块。#else
或#elif
指令%28(如果有%29被处理)。在前一种情况下,代码块由#else
指令是无条件编译的。在后一种情况下,#elif
指令的作用就好像它是#if
指令:检查条件、编译或跳过基于结果的受控代码块,在后一种情况下则处理后续的代码块。#elif
和#else
指令。条件预处理块被#endif
指令。
状态评价
#if, #elif
表达式是一个常量表达式。
如果表达式中包含形式中的一元运算符defined
标识符或defined (
标识符)
,首先对其进行评价。结果是1
如果标识符是定义为宏名称或者标识符是__has_include
%28,因为C++1
7%29,否则结果是0
...
在宏观扩展和评估之后defined
运算符,则任何非布尔文字,而当前也未定义为宏名称,而是将其替换为数字。0
...
如果表达式的计算值为非零值,则包含受控代码块,否则跳过。
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
检查标识符是否为定义为宏名称...
#ifdef
标识符实质上等同于#if defined(
标识符)
...
#ifndef
标识符实质上等同于#if !defined(
标识符)
...
例
二次
#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
}
二次
产出:
二次
1: yes
2: yes
3: yes
二次
缺陷报告
以下行为更改缺陷报告追溯应用于先前发布的C++标准。
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 |
另见
C有条件包含的文档
*。
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。