用 #ifdef 控制代码编译需先定义宏,否则无效;#ifdef 仅判断宏是否存在,判值须用 #if;宏名应加前缀防冲突,头文件卫士推荐 #pragma once 或唯一宏名。
怎么用 #ifdef 控制一段代码是否编译
直接靠 #ifdef + #endif 包住代码块,前提是前面定义过对应宏。没定义就跳过,定义了才参与编译——这是最基础也最容易漏掉“定义”这步的用法。
常见错误现象:#ifdef DEBUG_LOG 写了,但整个项目根本没 #define DEBUG_LOG,结果日志代码永远不生效,还怀疑是不是语法写错了。
- 定义宏的位置很关键:放在头文件开头、源文件顶部,或更稳妥的是通过编译器参数传入(比如
g++ -DDEBUG_LOG) - 如果只在某个 .cpp 里
#define,那它只对这个文件生效;跨文件要用头文件或编译选项 - 别用
#ifdef DEBUG_LOG == 1——#ifdef只看宏是否存在,不看值;要判值得用#if DEBUG_LOG == 1
#if 和 #ifdef 到底该选哪个
#ifdef 只检查宏是否被定义过,不管它等于几;#if 能算表达式,支持数字比较、逻辑运算,但要求宏必须是整型常量(或能展开成整型常量的宏)。
使用场景举例:你想让调试等级可配置,#define LOG_LEVEL 2,然后用 #if LOG_LEVEL >= 3 控制详细日志是否编译,这时必须用 #if。
立即学习“C++免费学习笔记(深入)”;
-
#ifdef FOO→ 安全,适合开关型标志(有/无) -
#if FOO > 0→ 要求FOO是整数宏,否则预处理器报错:error: token "FOO" is not valid in preprocessor expressions - 宏里带函数调用、字符串字面量、类型关键字?别想在
#if里用,预处理器不认识这些
怎么避免宏开关污染全局命名空间
宏没有作用域,一旦定义就一路有效到 #undef 或文件结束。多人协作时,一个模块定义了 ENABLE_CACHE,另一个模块也用同名宏但含义不同,编译可能不报错,行为却错乱。