17.3 有条件编译
条件编译用于在预处理阶段按条件选择代码片段,常见场景是标准版本差异、实现能力探测和特性开关。
1. defined 运算符
defined 标识符 或 defined(标识符) 会在预处理表达式中产生 1 或 0,用于判断宏是否已定义。
c
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)
#define USE_C23 1
#else
#define USE_C23 0
#endif1
2
3
4
5
2
3
4
5
2. 条件指令族
#if、#elif、#else、#endif 构成通用分支;#ifdef 与 #ifndef 是“只检查是否定义”的简写;C23 增加了 #elifdef 与 #elifndef,可让多分支条件更紧凑。若目标仍是 C11/C17,可写成 #elif defined(...) 以保持兼容。
c
#ifdef _WIN32
#define PATH_SEP "\\"
#elifdef __unix__
#define PATH_SEP "/"
#else
#define PATH_SEP "/"
#endif1
2
3
4
5
6
7
2
3
4
5
6
7
3. 条件表达式的语义边界
#if 里的表达式发生在预处理阶段,只能基于宏展开后的常量表达式计算,不能直接读取运行期对象值。把预处理条件和运行期 if 区分清楚,能避免“为什么这段分支没有生效”的常见误判。
c
#define FEATURE_FLAG 1
#if FEATURE_FLAG
/* 编译期保留 */
#endif1
2
3
4
5
2
3
4
5
当条件依赖外部构建参数时,建议集中在少量配置头中定义,再由业务代码读取统一宏,避免条件分支散落到各处。