条件编译指令根据不同条件,生成不同的代码进行编译。格式为:
#if 条件
代码
#elif 条件
代码
#else
代码
#endif
例如:
#if 1
AAAAAA
#else
BBBBBB
#endif
#if 0
CCCCCC
#else
DDDDDD
#endif
经过预处理后得到:
AAAAAA
CCCCCC
预处理运算符 defined 用于判断宏是否被 定义。例如:
#if defined(DEBUG)
#define LOG_DEBUG(fmt, ...) printf("[DEBUG]" fmt, ##__VA_ARGS__)
#else
#define LOG_DEBUG(...)
#endif
如果定义了 DEBUG,则 LOG_DEBUG 扩展为 printf
否则,LOG_DEBUG 定义为空
此外,对于单个宏定义的判断有一组简化的预处理指令:
| 指令 | 标准 | 说明 |
|---|---|---|
#ifdef 宏 |
C89 | 等价于 #if defined(宏) |
#ifndef 宏 |
C89 | 等价于 #if !defined(宏) |
#elifdef 宏 |
C23 | 等价于 #elif defined(宏) |
#elifndef 宏 |
C23 | 等价于 #elif !defined(宏) |
__has_include 是 C23 标准的新特性。预处理运算符 __has_include 用于判断文件是否被 包含。例如:
#if !__has_include("header.h")
#include "header.h"
#endif
如果没有包含 header.h,则进行包含
__has_embed 是 C23 标准的新特性。预处理运算符 __has_embed 用于判断文件是否被 嵌入。例如:
#if !__has_embed("image.png")
const uint8_t image_data[] =
{
#embed "image.png"
};
#endif
如果没有嵌入 image.png,则进行嵌入
__has_c_attribute 是 C23 标准的新特性。预处理运算符 __has_c_attribute 用于判断 C 语言的属性是否被支持。例如:
#if !__has_c_attribute(nodiscard)
[[nodiscard]]
#endif
int sum(int x, int y)
{
return x + y;
}
如果支持 nodiscard 属性,则使用该属性
C23 standard (ISO/IEC 9899:2024):
6.10.1 Conditional inclusion (p: TBD)
C17 standard (ISO/IEC 9899:2018):
6.10.1 Conditional inclusion (p: 118-119)
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