2457

12 分钟

#C 语言的预处理条件编译指令

条件编译指令根据不同条件,生成不同的代码进行编译。格式为:

#if 条件 代码 #elif 条件 代码 #else 代码 #endif

例如:

#if 1 AAAAAA #else BBBBBB #endif #if 0 CCCCCC #else DDDDDD #endif

经过预处理后得到:

AAAAAA CCCCCC

#预处理运算符 defined

预处理运算符 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

预处理运算符 __has_include 用于判断文件是否被 包含。例如:

#if !__has_include("header.h") #include "header.h" #endif
  • 如果没有包含 header.h,则进行包含

#预处理运算符 __has_embed

预处理运算符 __has_embed 用于判断文件是否被 嵌入。例如:

#if !__has_embed("image.png") const uint8_t image_data[] = { #embed "image.png" }; #endif
  • 如果没有嵌入 image.png,则进行嵌入

#预处理运算符 __has_c_attribute

预处理运算符 __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

创建于 2025/9/3

更新于 2025/9/3