条件包含

预处理器支持源文件的各个部分的条件编译。此行为由 #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 指令测试指定条件(见下文),如果指定的条件求值为 true ,则编译控制的代码块。这种情况下忽略后续的 #else#elif 指令。反之,如果指定的条件求值为 false ,则跳过控制的代码块,并处理后续的 #else#elif 指令(若存在)。在前一情况下,无条件编译 #else 指令控制的代码块。在后一情况下, #elif 指令的作用就像是一个 #if 指令:检查条件,基于结果编译或跳过控制的代码块,然后在后一情况下处理后续的 #elif#else 指令。条件预处理块以 #endif 指令终止。

条件求值

#if, #elif

表达式 是常量表达式,仅使用常量和用 #define 指令定义的标识符。任何非常量,未以 #define 指令定义的标识符,求值为0

表达式可以含有形式为 defined 标识符defined (标识符) 的一元运算符,若用 #define 指令定义了该 标识符 ,则返回 1 ,否则返回 0 。若 表达式 求值为非零值,则包含该控制代码块并跳过其他。若所用的任何标识符不是常量,则用 0 替换它。

注意: #if cond1 ... #elif cond2#if cond1 ... #else 后随 #if cond3 有别,因为若 cond1 为真,则跳过第二个 #if 被跳过,且 cond3 不必为良式,而 #elifcond2 必须是合法表达式。

(C11 前)

#ifdef, #ifndef

检查是否用 #define 指令定义了标识符。

#ifdef 标识符 本质上等价于 #if defined 标识符

#ifndef 标识符 本质上等价于 #if !defined 标识符

示例

#define ABCD 2
#include <stdio.h>
 
int main(void)
{
 
#ifdef ABCD
    printf("1: yes\n");
#else
    printf("1: no\n");
#endif
 
#ifndef ABCD
    printf("2: no1\n");
#elif ABCD == 2
    printf("2: yes\n");
#else
    printf("2: no2\n");
#endif
 
#if !defined(DCBA) && (ABCD < 2*4-3)
    printf("3: yes\n");
#endif
}

输出:

1: yes
2: yes
3: yes

引用

  • C11 standard (ISO/IEC 9899:2011):
  • 6.10.1 Conditional inclusion (p: 162-164)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.10.1 Conditional inclusion (p: 147-149)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.8.1 Conditional inclusion

参阅