条件包含

来自cppreference.com
 
 
C++ 语言
 
 

预处理器支持有条件地编译部分源文件。这一行为由 #if#else#elif#ifdef#ifndef#endif 指令所控制。

目录

[编辑] 语法

#if 表达式
#ifdef 表达式
#ifndef 表达式
#elif 表达式
#else
#endif

[编辑] 解释

条件编译预处理块由 #if#ifdef#ifndef 指令开始,并可选地包含任意多个 #elif 指令,接下来是至多一个可选的 #else 指令,并以 #endif 指令结束。嵌套的条件编译区块会被单独处理。

各个 #if#elif#else#ifdef#ifndef 指令所控制的代码块在第一个不属于内部嵌套的条件编译区块的 #elif#else#endif 指令处结束。

#if#ifdef#ifndef 指令测试其所指定的条件(见下文),如果条件求值为真,则编译其控制的代码块。此时后续的 #else#elif 指令将被忽略。否则,如果所指定的条件求值为假,则将跳过其所控制的代码块,然后处理后续的 #else#elif 指令(如果存在)。前一种情况下,#else 指令所控制的代码块将会被无条件地进行编译。后一种情况下,#elif 指令按照与 #if 指令相同的方式执行:即测试条件是否满足,并根据其结果决定编译或跳过其所控制的代码块,后一种情况下继续处理后续的 #elif#else 指令。条件编译区块以 #endif 指令结束。

[编辑] 条件的求值

[编辑] #if 和 #elif

表达式是一个常量表达式。

如果表达式中包含形如“defined 标识符”或“defined (标识符)”的一元运算符,那么首先对其求值。当这个标识符已经被定义为宏名或者这个标识符__has_include (C++17 起)时其结果为 1,否则结果为 0

在进行宏替换并求值 defined 运算符之后,除布尔字面量或已被定义为宏名的标识符以外的每个标识符,都被替换为数字 0

表达式求值为非零值时,被其控制的代码块将被包含,否则将被跳过。

注:#if cond1 ... #elif cond2#if cond1 ... #else 后面跟着 #if cond3 是不同的,因为当 cond1 为真时第二个 #if 将被跳过,且 cond3 并不需要是良构的,而 #elif 中的 cond2 则必须是有效的表达式。

(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 应用于 出版时的行为 正确行为
CWG 1955 C++14 失败的 #elif 中的表达式被要求有效 失败的 elif 被跳过

[编辑] 另请参阅

条件包含C 文档